Вы находитесь на странице: 1из 10

7.2.9.

Aninhado juntar o Optimization


At data de MySQL 5.0.1, a sintaxe para expressar junta reserva aninhado junta. A seguinte discusso consulta sintaxe juntar descrita na seo 13.2.7.1, JUNTA a sintaxe. A sintaxe do table_factor prolongada em comparao com o padro do SQL. O ltimo aceita somente o table_reference, no uma lista deles dentro de um par dos parnteses. Esta uma extenso conservadora se ns considerarmos cada vrgula em uma lista de artigos do table_reference como o equivalente a um interno junta. Por exemplo:
SELECIONAR * do T1 JUNTAR ESQUERDA (t2, T3, t4) EM (t2.a=t1.a E t3.b=t1.b E t4.c=t1.c)

equivalente a:
SELETO * do T1 DEIXADO JUNTAR (a CRUZ do t2 JUNTA A CRUZ T3 JUNTA t4) EM (t2.a=t1.a E t3.b=t1.b E t4.c=t1.c)

Em MySQL, a CRUZ JUNTA um equivalente sinttico a INTERNO JUNTA (podem se substituir). No SQL padro, no so equivalentes. INTERNO JUNTAR usado com SOBRE uma clusula; A CRUZ JUNTA usada de outra maneira. Nas verses de MySQL antes de 5.0.1, os parnteses nos table_references foram omitidos apenas e todos juntam operaes foram agrupados esquerda. No general, os parnteses podem ser ignorados dentro juntam as expresses que contm somente interno juntam operaes. Aps ter removido os parnteses e ter agrupado operaes esquerda, a expresso juntar:
o T1 DEIXADO JUNTA (o t2 ESQUERDO JUNTA o T3 em t2.b=t3.b OU t2.b NULO) em t1.a=t2.a

transforma na expresso:
(o T1 DEIXADO JUNTA o t2 em t1.a=t2.a) JUNTAR ESQUERDA o T3 em t2.b=t3.b OU t2.b NULO

Ainda, as duas expresses no so equivalentes. Para ver isto, supr que o T1 das tabelas, o t2, e o T3 tm o seguinte estado:

O T1 da tabela contem as fileiras (1), (2) O t2 da tabela contem a fileira (1.101)

O T3 da tabela contem a fileira (101)

Neste caso, a primeira expresso retorna um resultado ajustado including as fileiras (1.1.101.101), (2, ZERO, ZERO, ZERO), visto que a segunda expresso retorna as fileiras (1.1.101.101), (2, ZERO, ZERO, 101):
mysql> SELETO * - > do T1 - > SAIDO JUNTAR - > (o t2 ESQUERDO JUNTA o T3 em t2.b=t3.b OU t2.b NULO) - > em t1.a=t2.a; +------+-----+------+------+ | a | a | b | b | +------+------+------+------+ | 1 | 1 | 101 | 101 | | 2 | ZERO | ZERO | ZERO | +------+-----+------+------+ o mysql> SELETO * - > DE (o T1 DEIXADO JUNTA o t2 em t1.a=t2.a) - > JUNTA ESQUERDA o T3 - > em t2.b=t3.b OU em t2.b NULO; +------+------+------+------+ | a | a | b | b | +-----+------+------+------+ | 1 | 1 | 101 | 101 | | 2 | ZERO | ZERO | 101 | +------+------+------+------+

No seguinte exemplo, um exterior junta a operao usado junto com um interno junta a operao:
o T1 DEIXADO JUNTA (t2, T3) em t1.a=t2.a

Essa expresso no pode ser transformada na seguinte expresso:


o T1 DEIXADO JUNTA o t2 em t1.a=t2.a, T3.

Para os estados dados da tabela, as duas expresses retornam jogos diferentes das fileiras:
o mysql> SELETO * - > do T1 DEIXADO JUNTA (t2, T3) em t1.a=t2.a; +------+------+------+------+ | a | a | b | b | +------+-----+------+------+ | 1 | 1 | 101 | 101 | | 2 | ZERO | ZERO | ZERO | +------+------+------+------+ o mysql> SELETO * - > do T1 DEIXADO JUNTA o t2 em t1.a=t2.a, T3; +------+------+------+------+ | a | a | b | b | +------+------+------+------+ | 1 | 1 | 101 | 101 | | 2 | ZERO | ZERO | 101 | +------+------+------+------+

Conseqentemente, se ns omitirmos os parnteses em uma expresso juntar com exterior juntam operadores, ns puderam mudar o resultado ajustado para a expresso original. Mais exatamente, ns no podemos ignorar parnteses no operando direito do exterior esquerdo juntamos a operao e no operando esquerdo de uma direita juntar a operao. Ou seja ns no podemos ignorar parnteses para as expresses internas da tabela de exterior juntamos operaes. Os parnteses para o outro operando (operando para a tabela exterior) podem ser ignorados. A seguinte expresso:

(T1, t2) SAIDO JUNTAR o T3 em P (t2.b, t3.b)

equivalente a esta expresso:


o T1, t2 DEIXADO JUNTA o T3 em P (t2.b, t3.b)

para algum T1 das tabelas, t2, T3 e alguns atributos t2.b e t3.b. do excesso da condio P. Sempre que a ordem da execuo das operaes juntar em uma expresso juntar (join_table) no da esquerda para a direita, ns falamos sobre aninhado juntamos. Considerar as seguintes perguntas:
SELECIONAR * do T1 JUNTAR ESQUERDA (o t2 JUNTA ESQUERDA o T3 em t2.b=t3.b) em t1.a=t2.a ONDE t1.a > 1 SELETO * do T1 DEIXADO JUNTAM (t2, T3) em t1.a=t2.a ONDE (t2.b=t3.b OU t2.b NULO) E t1.a > 1

Aquelas perguntas so consideradas conter estes aninhados juntam:


o t2 DEIXADO JUNTA o T3 no t2 de t2.b=t3.b, T3

Aninhados juntam so dados forma na primeira pergunta com uma esquerda juntam a operao, visto que na segunda pergunta so dados forma com um interno juntam a operao. Na primeira pergunta, os parnteses podem ser omitidos: A estrutura gramatical da expresso juntar ditar a mesma ordem da execuo para junta operaes. Para a segunda pergunta, os parnteses no podem ser omitidos, embora a expresso juntar aqui possa ser interpretada unambiguously sem eles. (Em nossa sintaxe prolongada os parnteses (t2, T3) da segunda pergunta so requeridos dentro, embora terica a pergunta poderia ser analisada gramaticalmente sem eles: Ns ainda teramos a estrutura sinttica unambiguous para a pergunta porque a ESQUERDA JUNTA e SOBRE jogaramos o papel dos delimitadores esquerdos e direitos para a expresso (t2, o T3).) Os exemplos precedentes demonstram estes pontos:

Para juntar as expresses que envolvem somente interno junta (e nao exterior junta), parnteses pode ser removido. Voc pode remover os parnteses e avaliar-lhe esquerda a direita (ou, no fato, pode avaliar as tabelas em toda a ordem). O mesmo no verdadeiro, no general, para exterior junta ou para exterior junta misturado com interno junta. A remoo dos parnteses pode mudar o resultado.

As perguntas com exterior aninhado juntam so executadas na mesma maneira do encanamento que as perguntas com interno juntam. Mais exatamente, uma variao do aninh-lao junta o algoritmo explorada. Recordar por que schema que algortmico o aninh-lao junta executa uma pergunta. Supr que ns temos uma pergunta juntar sobre T1 de 3 tabelas, T2, T3 do formulrio:
SELECIONAR * do T1 INTERNO JUNTAR o T2 em P1 (T1, T2) INTERNO JUNTAM o T3 em P2 (T2, T3) ONDE P (T1, T2, T3).

Aqui, P1 (T1, T2) e P2 (T3, T3) so algum juntam circunstncias (em expresses), visto que P (T1, t2, T3) colunas excedentes de uma circunstncia do T1 das tabelas, o T2, T3. O aninh-lao junta o algoritmo executaria esta pergunta na seguinte maneira:
PARA cada T1 da fileira no T1 {PARA cada t2 da fileira no T2 tais que P1 (T1, t2) {PARA cada T3 da fileira no T3 tais que P2 (t2, T3) {SE P (T1, t2, T3) {t: =t1||t2||t3; SADA t; }}}}

Os meios da notao t1||t2||t3 uma fileira construda concatenando as colunas do T1 das fileiras, do t2, e do T3. Em alguns dos seguintes exemplos, ZERO onde um nome da fileira aparece os meios que o ZERO usado para cada coluna dessa fileira. Por exemplo, t1||t2||NULL significa uma fileira construda concatenando as colunas do T1 das fileiras e do t2, e o ZERO para cada coluna do T3. Agora vamos considerar uma pergunta com exterior aninhado junta:
SELECIONAR * do T1 JUNTAR ESQUERDA (o T2 JUNTA ESQUERDA o T3 em P2 (T2, T3)) Em P1 (T1, T2) ONDE P (T1, T2, T3).

Para esta pergunta, ns modificamos o teste padro do aninh-lao para comear:


PARA cada T1 da fileira em T1 {BOOL f1: =FALSE; PARA cada t2 da fileira no T2 tais que P1 (T1, t2) {BOOL f2: =FALSE; PARA cada T3 da fileira no T3 tais que P2 (t2, T3) {SE P (T1, t2, T3) {t: =t1|| t2||t3; SADA t; } f2=TRUE; f1=TRUE; } SE (! f2) {SE P (T1, t2, ZERO) {t: =t1||t2||NULL; SADA t; } f1=TRUE; }} SE (! f1) {SE P (T1, ZERO, ZERO) {t: =t1||NULL||NULL; SADA t; }}}

No general, para todo o lao aninhado para a primeira tabela interna em um exterior juntar a operao, uma bandeira introduzida que seja desligada antes do lao e verificada aps o lao. A bandeira est girada em quando para a fileira atual da tabela exterior um fsforo da tabela que representa o operando interno encontrado. Se na extremidade do ciclo do lao a bandeira estiver ainda fora, nenhum fsforo estve encontrado para a fileira atual da tabela exterior. Neste caso, a fileira complementada por valores NULOS para as colunas das tabelas

internas. A fileira do resultado passada verificao final para a sada ou no lao aninhado seguinte, mas somente se a fileira se satisf a condio juntar de exterior toda encaixado junta. Em nosso exemplo, o exteriores juntam a tabela expressada pela seguinte expresso so encaixados:
(o T2 DEIXADO JUNTA o T3 em P2 (T2, T3))

Anotar isso para a pergunta com interno junta, o optimizer poderia escolher uma ordem diferente de laos aninhados, tais como este:
PARA cada T3 da fileira no T3 {PARA cada t2 da fileira no T2 tais que P2 (t2, T3) {PARA cada T1 da fileira no T1 tais que P1 (T1, t2) {SE P (T1, t2, T3) {t: =t1||t2||t3; SADA t; }}}}

Para as perguntas com exterior junta, o optimizer pode escolher somente tal ordem onde os laos para tabelas exteriores precedem laos para tabelas internas. Assim, para nossa pergunta com exterior junta, only uma ordem se aninhar possvel. Para a seguinte pergunta, o optimizer avaliar dois assentamentos diferentes:
SELECIONAR * o T1 JUNTA ESQUERDA (T2, T3) em P1 (T1, T2) E em P2 (T1, T3) ONDE P (T1, T2, T3)

Os assentamentos so estes:
PARA cada T1 da fileira em T1 {BOOL f1: =FALSE; PARA cada t2 da fileira no T2 tais que P1 (T1, t2) {PARA cada T3 da fileira no T3 tais que P2 (T1, T3) {SE P (T1, t2, T3) {t: =t1||t2||t3; SADA t; } f1: =TRUE}} SE (! f1) {SE P (T1, ZERO, ZERO) {t: =t1||NULL|| NULL; SADA t; }}}

e:
PARA cada T1 da fileira em T1 {BOOL f1: =FALSE; PARA cada T3 da fileira no T3 tais que P2 (T1, T3) {PARA cada t2 da fileira no T2 tais que P1 (T1, t2) {SE P (T1, t2, T3) {t: =t1||t2||t3; SADA t; } f1: =TRUE}} SE (! f1) {SE P (T1, ZERO, ZERO) {t: =t1||NULL|| NULL; SADA t; }}}

Em ambos os assentamentos, o T1 deve ser processado no lao exterior porque usado em um exterior junta. O T2 e o T3 so usados em um interno juntam, de modo que juntar deva ser processado no lao interno. Entretanto, porque juntar um interno juntar, T2 e T3 pode ser processado em uma ou outra ordem. Quando discutir o algoritmo do aninh-lao para interno junta, ns omitimos alguns detalhes cujo o impacto no desempenho da execuo da pergunta pode ser

enorme. Ns no mencionamos circunstncias empurradas-para baixo so-called. Supr que nosso ONDE a condio P (T1, T2, T3) pode ser representada por uma frmula conjunctive:
P (T1, T2, T2) = C1 (T1) E C2 (T2) E C3 (T3).

Neste caso, MySQL usa realmente o seguinte schema do aninh-lao para a execuo da pergunta com interno junta:
PARA cada T1 da fileira no T1 tais que C1 (T1) {PARA cada t2 da fileira no T2 tais que P1 (T1, t2) E C2 (t2) {PARA cada T3 da fileira no T3 tais que P2 (t2, T3) E C3 (T3) {SE P (T1, t2, T3) {t: =t1||t2||t3; SADA t; }}}}

Voc v que cada uma das oraes conjuntivas C1 (T1), C2 (T2), C3 (T3) est eliminada do lao o mais interno ao lao o mais exterior onde pode ser avaliado. Se C1 (T1) for uma condio muito restritiva, este pushdown da condio pode extremamente reduzir o nmero das fileiras do T1 da tabela passado aos laos internos. Em conseqncia, o momento de execuo para a pergunta pode melhorar immensely. Para uma pergunta com exterior junta, ONDE a circunstncia deve ser verificada somente depois que se encontrou que a fileira atual da tabela exterior tem um fsforo nas tabelas internas. Assim, o optimization de empurrar circunstncias fora dos laos aninhados internos no pode ser aplicado diretamente s perguntas com exterior junta. Aqui ns temos que introduzir os predicados empurrados-para baixo condicionais guardados pelas bandeiras em que esto girados quando um fsforo foi encontrado. Para nosso exemplo com exterior junta com:
P (T1, T2, T3) =C1 (T1) E C (T2) E C3 (T3)

o schema do aninh-lao que usa circunstncias empurradas-para baixo guardadas olha como este:
PARA cada T1 da fileira no T1 tais que C1 (T1) {BOOL f1: =FALSE; PARA cada t2 da fileira no T2 tais que P1 (T1, t2) E (f1? C2 (t2): RECTIFICAR) {BOOL f2: =FALSE; PARA cada T3 da fileira no T3 tais que P2 (t2, T3) E (f1&&f2? C3 (T3): RECTIFICAR) {SE (f1&&f2? RECTIFICAR: (C2 (t2) E C3 (T3))) {t: =t1||t2||t3; OUTPUT t; } f2=TRUE; f1=TRUE; } SE (! f2) {SE (f1? VERDADEIRO: (T2) && C2 P (T1, t2, ZERO)) {t: =t1||t2||NULL; SADA t; } f1=TRUE; }} SE (! f1 && P (T1, ZERO, ZERO)) {t: =t1||NULL||NULL; SADA t; }}

Em predicados gerais, empurrados-para baixo pode ser extrado de juntam condies tais como P1 (T1, T2) e P (T2, T3). Neste caso, um predicado empurrado-para baixo guardado tambm por uma bandeira que impea verificar

o predicado para ver se h a fileira Nulo-complementada gerada corresponder exterior junte a operao. Anotar que o acesso pela chave de uma tabela interna a outra no mesmo aninhado junta est proibido se for induzido por um predicado do ONDE circunstncia. (Ns poderamos usar o acesso chave condicional neste caso, mas esta tcnica no empregada ainda em MySQL 5.0.)

7.2.6. Optimization da fuso do ndice


7.2.6.1. O algoritmo do acesso da interseo da fuso do ndice 7.2.6.2. O algoritmo do acesso da unio da fuso do ndice 7.2.6.3. O algoritmo do acesso da Sorte-Unio da fuso do ndice O mtodo da fuso do ndice usado recuperar fileiras com diversos varreduras da escala e fundir seus resultados em um. A fuso pode produzir unies, intersees, ou unio--intersees de suas varreduras subjacentes. Nota: Se voc promover de uma verso precedente de MySQL, voc deve estar ciente que este tipo de junta o optimization est introduzido primeiramente em MySQL 5.0, e representa uma mudana significativa no comportamento no que diz respeito aos ndices. (Anteriormente, MySQL podia se usar em o mais somente um ndice para cada tabela referenced.) Em EXPLICAR a sada, o mtodo da fuso do ndice aparece como o index_merge no tipo coluna. Neste caso, a coluna chave contem uma lista dos ndices usados, e key_len contem uma lista das peas chaves as mais longas para aqueles ndices. Exemplos:
SELECIONAR * do tbl_name ONDE key1 = 10 OU key2 = 20; SELECIONAR * do tbl_name ONDE (key1 = 10 OU key2 = 20) E non_key=30; SELECIONAR * do T1, t2 em ONDE (t1.key1 (1.2) OU t1.key2 GOSTAM de value%) E t2.key1=t1.some_col; SELECIONAR * do T1, t2 ONDE t1.key1=1 E (t2.key1=t1.some_col OU t2.key2=t1.some_col2);

O mtodo da fuso do ndice tem diversos algoritmos do acesso (vistos no campo extra de EXPLICAR a sada):

Usar-se cruza-se (...) Usando a unio (...) Usando o sort_union (...)

As seguintes sees descrevem estes mtodos em um detalhe mais grande. Nota: O algoritmo do optimization da fuso do ndice tem as seguintes deficincias sabidas:

Se uma varredura da escala for possvel em alguma chave, uma fuso do ndice no est considerada. Por exemplo, considerar esta pergunta:
SELECIONAR * do T1 ONDE (goodkey1 < 10 OU goodkey2 < 20) E badkey < 30;

Para esta pergunta, duas plantas so possveis:


o o

Uma varredura da fuso do ndice usando (goodkey1 < 10 OU goodkey2 < 20) a circunstncia. Uma varredura da escala usando o badkey < circunstncia 30.

Entretanto, o optimizer considera somente a segunda planta.

Se sua pergunta tiver um complexo ONDE a clusula com profundamente E/OU se aninhar e MySQL no escolham a planta optimal, tentar distribuir termos usando as seguintes leis da identidade:
(x E y) OU z = (x OU z) E (y OU z) (x OU y) E z = (x E z) OU (y E z)

A fuso do ndice no aplicvel aos ndices fulltext. Ns planeamos estend-la para cobrir estes em uma liberao futura de MySQL.

A escolha entre variants possveis diferentes do mtodo de acesso da fuso do ndice e outros mtodos de acesso baseada em estimativas de custo de vrias opes disponveis.

7.2.6.1. O algoritmo do acesso da interseo da fuso do ndice


Este algoritmo do acesso pode ser empregado quando a ONDE a clusula estve convertida a diversas condies da escala nas chaves diferentes combinadas com E, e cada condio uma do seguinte:

Neste formulrio, onde o ndice tem exatamente as peas de N (isto , todas as peas do ndice so cobertas):
key_part1=const1 E key_part2=const2 E key_partN=constN

Alguma condio da escala sobre uma chave preliminar de uma tabela de InnoDB ou de BDB.

Exemplos:
SELECIONAR * de innodb_table ONDE primary_key < 10 E key_col1=20; SELECIONAR * do tbl_name ONDE (key1_part1=1 E key1_part2=2) E key2=2;

O algoritmo da interseo da fuso do ndice executa varreduras simultneas em todos os ndices usados e produz a interseo das seqncias da fileira que recebe das varreduras fundidas do ndice. Se todas as colunas usadas na pergunta forem cobertas pelos ndices usados, as fileiras cheias da tabela no esto recuperadas (EXPLICAR a sada contem usando o ndice no campo extra neste caso). Est aqui um exemplo de tal pergunta:
SELECIONAR A CONTAGEM (*) do T1 ONDE key1=1 E key2=1;

Se os ndices usados no cobrirem todas as colunas usadas na pergunta, as fileiras cheias esto recuperadas somente quando as condies da escala para todas as chaves usadas so satisfeitas. Se uma das circunstncias fundidas for uma condio sobre uma chave preliminar de uma tabela de InnoDB ou de BDB, no est usada para a recuperao da fileira, mas est usada filtrar para fora as fileiras recuperadas usando outras condies.

7.2.6.2. O algoritmo do acesso da unio da fuso do ndice


Os critrios da aplicabilidade para este algoritmo so similares queles para o algoritmo da interseo do mtodo da fuso do ndice. O algoritmo pode ser empregado quando a tabela ONDE a clusula estve convertida a diversas condies da escala nas chaves diferentes combinadas com OU, e cada condio so uma do seguinte:

Neste formulrio, onde o ndice tem exatamente as peas de N (isto , todas as peas do ndice so cobertas):
key_part1=const1 E key_part2=const2 E key_partN=constN

Alguma condio da escala sobre uma chave preliminar de uma tabela de InnoDB ou de BDB. Uma circunstncia para que o algoritmo da interseo do mtodo da fuso do ndice aplicvel.

Exemplos:
SELECIONAR * do T1 ONDE key1=1 OU key2=2 OU key3=3; SELECIONAR * de innodb_table ONDE (key1=1 E key2=2) OU (key3='foo E key4='bar') E key5=5;

Precedente/em seguida/acima de/ndice

7.2.6.3. O algoritmo do acesso da Sorte-Unio da fuso do ndice


Este algoritmo do acesso for empregado quando ONDE a clusula foi convertida a diversas condies da escala combinadas perto OU, mas para qual o algoritmo da unio do mtodo da fuso do ndice no aplicvel. Exemplos:
SELECIONAR * do tbl_name ONDE key_col1 < 10 OU key_col2 < 20; SELECIONAR * do tbl_name ONDE (key_col1 > 10 OU key_col2 = 20) E nonkey_col=30;

A diferena entre o algoritmo da sorte-unio e o algoritmo da unio que o algoritmo da sorte-unio deve primeiramente buscar a fileira IDs para todas as fileiras e as classificar antes de retornar alguma fileira.

Вам также может понравиться