Este artigo leva você a entender o método de acesso à tabela única do MySQL

prefácio

Para nós MySQL, usuários, MySQLé na verdade um software, que é o que mais usamos 查询功能. DBADe vez em quando, jogue um pouco 慢查询语句para otimização. Se nem sabemos como a consulta é executada, o que devemos otimizar, então é hora de dominar a tecnologia real.

1. Preparação de dados

No artigo anterior, sabemos que MySQL Serverexiste um 查询优化器módulo chamado . Depois que uma instrução de consulta é analisada, ela é entregue ao otimizador de consulta para otimização. O resultado da otimização é gerar o chamado plano de execução. Essa execução plano mostra quais índices devem ser usados ​​para a consulta, qual é a sequência de conexão entre as tabelas e, finalmente, o método fornecido pelo mecanismo de armazenamento será chamado de acordo com as etapas do plano de execução para realmente executar a consulta e o resultado da consulta será devolvido ao usuário. No entanto, o tópico de otimização de consulta é um pouco extenso e você precisa aprender como usá-lo antes de aprender como executá-lo, portanto, neste capítulo, vamos primeiro dar uma olhada em como o MySQL executa consultas de tabela única (ou seja, , há apenas uma tabela atrás da instrução from, o tipo mais simples de consulta~). No entanto, uma coisa a enfatizar é que você deve ler as partes anteriores sobre estrutura de registro, estrutura de página de dados e índice antes de estudar este capítulo. Se você não pode garantir que essas coisas foram totalmente dominadas, então este capítulo não é adequado para você

Para que possamos estudar sem problemas, primeiro criamos uma tabela:

mysql> USE testdb;

mysql> create table demo8 (    
id int not null auto_increment,    
key1 varchar(100),    
key2 int,    
key3 varchar(100),    
key_part1 varchar(100),    
key_part2 varchar(100),    
key_part3 varchar(100),    
common_field varchar(100), 
primary key (id),
key idx_key1 (key1),    
unique key idx_key2 (key2),    
key idx_key3 (key3),    
key idx_key_part(key_part1, key_part2, key_part3));

Um total de 1 índice clusterizado (chave primária) e 4 índices secundários foram criados para a tabela demo8:

  • Um índice clusterizado criado para a coluna id;
  • Um índice secundário criado para a coluna key1;
  • Um índice secundário exclusivo criado para a coluna key2;
  • Um índice secundário criado para a coluna key3;
  • Índice secundário composto (conjunto) criado para colunas key_part1, key_part2, key_part3.

Em seguida, precisamos inserir 20.000 registros para esta tabela e inserir valores aleatórios em todas as colunas, exceto na coluna id.

mysql> delimiter //
create procedure demo8data()
begin    
	declare i int;    
	set i=0;    
	while i<20000 do        
		insert into demo8(key1,key2,key3,key_part1,key_part2,key_part3,common_field) values(substring(md5(rand()),1,2),i+1,substring(md5(rand()),1,3),substring(md5(rand()),1,4),substring(md5(rand()),1,5),substring(md5(rand()),1,6),substring(md5(rand()),1,7));        
		set i=i+1;    
	end while;
end;
//
delimiter ;

mysql> call demo8data();

2. Método de acesso à tabela única

2.1 O conceito de método de acesso

Todos nós já passamos pela experiência de consultar um dicionário quando estávamos no ensino fundamental. Quando nosso vocabulário não atingiu um determinado nível, se quisermos saber a definição de uma palavra que nunca vimos antes, precisamos um dicionário. Em circunstâncias normais, iremos primeiro ao diretório do dicionário para encontrar o pinyin correspondente ou radicais chineses, localizar o número da página da palavra e, em seguida, virar diretamente para o número da página correspondente para visualizar a definição correspondente. Há também uma situação em que os dicionários com centenas de páginas podem ser pesquisados ​​página por página, da primeira à última página, quando você está muito ocioso e pode finalmente encontrá-lo. Ambas as formas podem obter os resultados que desejamos, mas o tempo e a energia gastos são muito diferentes. O mesmo vale para o MySQL. Para agilizar os dados da consulta, o conceito de índice de árvore B+ é proposto. Mas às vezes, se quisermos consultar todos os dados, temos que percorrer todas as páginas de dados linha por linha e página por página para obter os resultados.

Para a consulta de uma única tabela, os métodos de execução da consulta MySQL são divididos aproximadamente nos dois tipos a seguir:

2.1.1 Consulta usando varredura de tabela completa

Esse método é o que eu disse acima, percorrendo os registros linha por linha, página por página e adicionando os registros que atendem às condições de pesquisa ao conjunto de resultados. Embora esse método possa atender às nossas necessidades, a eficiência é sem dúvida a mais baixa.

2.1.2 Consultando com índices

Executar a consulta diretamente usando o método full table scan requer percorrer muitos registros e o custo pode ser muito alto. Assim como procuramos caracteres chineses no diretório do dicionário, se as condições de pesquisa na instrução de consulta do MySQL puderem usar um índice, usar diretamente o índice para executar a consulta pode acelerar o tempo de execução da consulta. As maneiras pelas quais os índices são usados ​​para realizar consultas podem ser divididas em várias categorias:

  • Consultas de equivalência em relação a chaves primárias ou índices secundários exclusivos
  • Consultas de equivalência em relação a índices secundários comuns
  • Consulta por intervalo de colunas indexadas
  • Ao escanear diretamente todo o índice

resumo

A maneira como o MySQL executa uma instrução de consulta é chamada de método de acesso ou tipo de acesso. A mesma instrução de consulta pode ser executada usando uma variedade de métodos de acesso diferentes. Embora os resultados finais da consulta sejam os mesmos, a eficiência da execução varia muito.

insira a descrição da imagem aqui

2,2 const

Localize um registro por sua coluna de chave primária:

mysql> select * from demo8 where id=9999;
+------+------+------+------+-----------+-----------+-----------+--------------+
| id   | key1 | key2 | key3 | key_part1 | key_part2 | key_part3 | common_field |
+------+------+------+------+-----------+-----------+-----------+--------------+
| 9999 | 34   | 9999 | 6c7  | 1823      | 24955     | 5deed4    | 3aebe82      |
+------+------+------+------+-----------+-----------+-----------+--------------+
1 row in set (0.00 sec)

Você ainda se lembra da estrutura do índice clusterizado B+ tree no MySQL B+ tree index? coluna de ID de chave de pequeno a grande. A árvore B+ é originalmente um homem baixo e gordo, com atributos únicos, ordenados e não vazios, a velocidade de localização de um registro de acordo com o valor da chave primária é muito rápida. Da mesma forma, é muito rápido localizar um registro com base na coluna de índice secundário exclusivo:

mysql> select * from demo8 where key2=8888;
+------+------+------+------+-----------+-----------+-----------+--------------+
| id   | key1 | key2 | key3 | key_part1 | key_part2 | key_part3 | common_field |
+------+------+------+------+-----------+-----------+-----------+--------------+
| 8888 | 12   | 8888 | fc9  | 7810      | 1c7ed     | 5d6dbc    | adbea8c      |
+------+------+------+------+-----------+-----------+-----------+--------------+
1 row in set (0.00 sec)

Com base no conhecimento dos artigos anteriores, a execução desta consulta é dividida em duas etapas:

  • A primeira etapa é localizar um registro de índice secundário do índice da árvore B+ correspondente a idx_key2 de acordo com a condição de comparação de equivalência entre a coluna key2 e a constante.
  • Na segunda etapa, o registro completo do usuário é obtido do índice clusterizado de acordo com o valor id do registro.

É muito, muito rápido para o MySQL localizar um registro através da comparação equivalente entre a chave primária ou a coluna de índice secundário único e a constante, então o método de acesso para localizar um registro através da chave primária ou a coluna de índice secundário único é definido como: const , significando nível constante, o custo é insignificante.

No entanto, este método de acesso const só é válido quando a coluna de chave primária ou a coluna de índice secundário exclusivo é comparada com uma constante de igualdade. Se a chave primária ou o índice secundário exclusivo for composto de várias colunas, cada índice nas Colunas de índice para ser comparado com constantes para equivalência, e este método de acesso const é válido (isso ocorre porque o único registro pode ser localizado apenas se todas as colunas no índice forem comparadas para equivalência).

Para um índice secundário exclusivo, o caso de consultar se a coluna é um valor NULL é especial:

mysql> select * from demo8 where key2 is null;

A única coluna de índice secundário não limita o número de valores NULL, portanto, a instrução acima pode acessar vários registros. A instrução acima não pode ser executada usando o método de acesso const. Quanto ao método de acesso, falaremos sobre ele logo abaixo

2.3 referência

Colunas de índice secundárias comuns são comparadas quanto à igualdade com constantes:

mysql> select * from demo8 where key1 = 'd9';
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| id    | key1 | key2  | key3 | key_part1 | key_part2 | key_part3 | common_field |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
|    59 | d9   |    59 | b7a  | 041b      | 5b1cf     | e342ac    | e103738      |
|   182 | d9   |   182 | 8bf  | 2b3c      | 08b7c     | a63ed0    | 40f2c52      |
|   401 | d9   |   401 | 137  | adbd      | dafba     | 581313    | ba72bf5      |
|  2114 | d9   |  2114 | d8b  | bf2a      | 117ae     | 69de3d    | f5467a5      |
|  2758 | d9   |  2758 | 2f7  | a159      | e3707     | f60f38    | 795ec06      |
|  3823 | d9   |  3823 | 682  | 347e      | f6195     | 6faa0d    | 5e55f78      |
|  4351 | d9   |  4351 | e92  | f3b4      | a159e     | d3e013    | e28ca48      |
|  5138 | d9   |  5138 | b41  | 1b10      | b9605     | cbe517    | b267144      |
|  5539 | d9   |  5539 | da1  | d30d      | c59b1     | 0c5d79    | ae57b7d      |
|  5604 | d9   |  5604 | ddc  | f0b0      | 00dbf     | f93c0e    | 3218cff      |
|  6050 | d9   |  6050 | 64e  | 22a4      | 69e69     | 7284ba    | 4a5b7d5      |
|  6147 | d9   |  6147 | 529  | cd38      | 71855     | 434168    | a426cbe      |
|  6428 | d9   |  6428 | a38  | c00f      | 9f710     | 9fb7c5    | a722b51      |
|  6456 | d9   |  6456 | eb7  | d208      | 30539     | ee3ae4    | a6c4870      |
|  6473 | d9   |  6473 | c15  | da29      | cc897     | 1e35c3    | 4b5f135      |
|  6860 | d9   |  6860 | b01  | bad8      | 4e3a9     | e83331    | 0cd3b9d      |
|  7257 | d9   |  7257 | fa6  | d537      | a4afe     | bbc5d8    | e11e937      |
|  7333 | d9   |  7333 | a97  | 5532      | 64097     | cb5d16    | 7e43077      |
|  7867 | d9   |  7867 | 3d7  | b341      | 0b0bb     | 7df721    | 8c64142      |
|  8265 | d9   |  8265 | a16  | 120b      | 9d372     | c17ce4    | c481ace      |
|  8371 | d9   |  8371 | 5be  | 7924      | 313f7     | 293487    | cb52072      |
|  8738 | d9   |  8738 | c05  | 7123      | b61b1     | c8d819    | e310cbf      |
|  9005 | d9   |  9005 | 44e  | e857      | 4075c     | 8460a0    | 409cb1d      |
|  9006 | d9   |  9006 | d8c  | 8c2b      | ed54f     | 3b8bfd    | 268fcce      |
|  9362 | d9   |  9362 | 5cb  | 9d70      | 05937     | 1b70d2    | a866a32      |
|  9449 | d9   |  9449 | ab8  | f9c6      | c1917     | 5ffe25    | ff88471      |
| 10146 | d9   | 10146 | 07f  | 31a7      | c30c4     | 7c2e48    | 6c5c562      |
| 10197 | d9   | 10197 | 85a  | 4796      | e5ff9     | d12af4    | 20be699      |
| 10223 | d9   | 10223 | 94b  | c57e      | adfb6     | b93c19    | a7c944b      |
| 10285 | d9   | 10285 | 9ab  | f33d      | 69e5c     | 35a651    | 0953db7      |
| 10621 | d9   | 10621 | a29  | a92b      | fbf80     | 83f1e2    | d167770      |
| 11133 | d9   | 11133 | 560  | 97af      | 35f38     | ceb1b9    | 6e89ca8      |
| 11265 | d9   | 11265 | fcc  | e7d7      | 0243e     | b52571    | 89ea417      |
| 11557 | d9   | 11557 | 1c0  | 7f66      | 0898f     | d41cfc    | e759975      |
| 11614 | d9   | 11614 | de5  | 00f7      | fb3b3     | 93dc1a    | bbe8993      |
| 11672 | d9   | 11672 | f3f  | 9fe4      | da2dd     | 82f711    | 436f3d4      |
| 12477 | d9   | 12477 | d58  | 0613      | 1df6d     | 40999a    | b748cd2      |
| 13789 | d9   | 13789 | 67b  | 5b30      | ab2f3     | 89f0ec    | 9e2d255      |
| 14050 | d9   | 14050 | 537  | bbdc      | 5e87e     | 4ac153    | 0346558      |
| 14363 | d9   | 14363 | 2ac  | 33f3      | e2b82     | 7e55c1    | 45ee579      |
| 14444 | d9   | 14444 | e47  | 6319      | 851b7     | 1d4c57    | e17a95b      |
| 14635 | d9   | 14635 | 16a  | 4d83      | 52b33     | 376017    | c853bc0      |
| 14646 | d9   | 14646 | 202  | 6fdd      | f2486     | 9900f3    | c29d0d6      |
| 15298 | d9   | 15298 | 074  | a7ee      | 6bc1d     | e96458    | 723b0f8      |
| 15489 | d9   | 15489 | 514  | 0bdc      | fb94c     | db5ce8    | 63797e8      |
| 16895 | d9   | 16895 | 4aa  | 921c      | 00b9e     | f07907    | bce779f      |
| 17587 | d9   | 17587 | 6aa  | 621b      | d521f     | a6c5ad    | 45fac89      |
| 18151 | d9   | 18151 | 87d  | cd74      | f7135     | 47d900    | 211303e      |
| 18255 | d9   | 18255 | 4dc  | b9e7      | 99bf2     | 55d0eb    | 3e6ce6c      |
| 18490 | d9   | 18490 | 6a2  | f0ff      | 85e86     | ed9bb8    | dca2cb4      |
| 18872 | d9   | 18872 | 404  | eeee      | 001c7     | 0e846d    | fae0876      |
| 19018 | d9   | 19018 | 142  | 80d7      | 2b9fd     | 77be32    | d6d8398      |
| 19228 | d9   | 19228 | a5b  | a125      | 795fa     | 108159    | 65acbf5      |
| 19537 | d9   | 19537 | 1ca  | 016a      | 3df13     | 3f5b9c    | 720de00      |
| 19940 | d9   | 19940 | 95c  | 6150      | 2696d     | 3f89b8    | d37d43a      |
| 19945 | d9   | 19945 | 538  | 6378      | a20a9     | 2b7b00    | 1865f1c      |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
56 rows in set (0.00 sec)

Os índices secundários comuns não limitam a exclusividade dos valores das colunas do índice, portanto, é possível encontrar vários registros correspondentes (como em nosso exemplo, um total de 56 linhas que satisfazem as condições foram correspondidas), ou seja, o uso de índices secundários para executar consultas O custo depende do número de registros de índice secundário correspondidos pelo valor equivalente. Se houver menos registros correspondentes, o custo de retornar à tabela ainda é relativamente baixo, portanto, o MySQL pode optar por usar um índice em vez de uma varredura completa da tabela para executar a consulta. O MySQL considera esta condição de pesquisa como uma comparação entre a coluna do índice secundário e o valor equivalente constante, e o método de acesso que usa o índice secundário para executar a consulta é chamado de: ref.
Para um índice secundário comum, vários registros consecutivos podem ser correspondidos após a comparação equivalente da coluna do índice, em vez de corresponder apenas a um registro, no máximo, como uma chave primária ou um índice secundário exclusivo, portanto, este acesso de referência O método é um pouco pior do que const, mas a eficiência ainda é muito alta quando o número de registros correspondentes é pequeno na comparação de equivalentes de índices secundários (se houver muitos registros de índices secundários correspondentes, o custo de retornar à tabela será muito alto).

Precisa prestar atenção às duas situações a seguir:

  • O caso em que o valor da coluna do índice secundário é NULL: Seja um índice secundário comum ou um índice secundário exclusivo, não há limite para o número de valores NULL contidos em suas colunas de índice, portanto, usamos a chave IS NULL form das condições de pesquisa só podem usar métodos de acesso de ref no máximo, não métodos de acesso const.
  • Para um índice secundário que contém várias colunas de índice, desde que a coluna de índice contínuo mais à esquerda seja uma comparação equivalente com uma constante, o método de acesso ref pode ser usadoidx_key_part(key_part1, key_part2, key_part3)
mysql> select * from demo8 where key_part1='6378';
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| id    | key1 | key2  | key3 | key_part1 | key_part2 | key_part3 | common_field |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| 19945 | d9   | 19945 | 538  | 6378      | a20a9     | 2b7b00    | 1865f1c      |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
1 row in set (0.00 sec)

mysql> select * from demo8 where key_part1='6378' and key_part2='a20a9';
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| id    | key1 | key2  | key3 | key_part1 | key_part2 | key_part3 | common_field |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| 19945 | d9   | 19945 | 538  | 6378      | a20a9     | 2b7b00    | 1865f1c      |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
1 row in set (0.00 sec)

mysql> select * from demo8 where key_part1='6378' and key_part2='a20a9' and key_part3='2b7b00';
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| id    | key1 | key2  | key3 | key_part1 | key_part2 | key_part3 | common_field |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
| 19945 | d9   | 19945 | 538  | 6378      | a20a9     | 2b7b00    | 1865f1c      |
+-------+------+-------+------+-----------+-----------+-----------+--------------+
1 row in set (0.00 sec)
  • Mas se as colunas de índice consecutivas mais à esquerda não forem todas comparações de valores iguais, seu método de acesso não poderá ser chamado de ref:
mysql> select * from demo8 where key_part1='6378' and key_part2>'a20a9';
Empty set (0.00 sec)

2.4 ref_or_null

Encontre os registros cujo valor de uma coluna de índice secundário é igual a uma determinada constante e também deseja encontrar os registros cujo valor é NULL

mysql> select * from demo8 where key1 = 'd9' or key is null;

Quando a consulta é executada usando um índice secundário em vez de uma varredura completa da tabela, o método de acesso usado por esse tipo de consulta é chamado ref_or_null. É equivalente a primeiro encontrar dois intervalos de registro consecutivos de key1 IS NULL e key1 = 'ef' da árvore B+ correspondente ao índice idx_key1 e, em seguida, retornar à tabela para encontrar registros de usuário completos de acordo com os valores de id nesses registros de índice secundário.

2,5 alcance

Os vários métodos de acesso apresentados anteriormente só são possíveis de usar ao comparar a coluna do índice com um determinado valor constante (ref_or_null é bastante peculiar e o valor de NULL também é calculado), às vezes as condições de pesquisa que enfrentamos são mais complexas:

mysql> select * from demo8 where key2 in (5555,6666) or (key2>=1234 and key2<=1235);
+------+------+------+------+-----------+-----------+-----------+--------------+
| id   | key1 | key2 | key3 | key_part1 | key_part2 | key_part3 | common_field |
+------+------+------+------+-----------+-----------+-----------+--------------+
| 1234 | 67   | 1234 | a2d  | 2779      | 18191     | 96a5b2    | 86c5afa      |
| 1235 | 6b   | 1235 | c48  | 43b4      | 0e1d1     | 27f9a0    | 1c17810      |
| 5555 | 0b   | 5555 | dc2  | 6b61      | dac52     | a0451f    | 187011e      |
| 6666 | 00   | 6666 | 9c3  | 99f8      | d22de     | 283e92    | 656f2f1      |
+------+------+------+------+-----------+-----------+-----------+--------------+
4 rows in set (0.00 sec)

Esta consulta pode ser executada por varredura de tabela completa, mas também pode ser executada usando índice secundário + retorno de tabela. Se a consulta for executada por índice secundário + retorno de tabela, então a condição de pesquisa neste momento não é necessária apenas A coluna de índice corresponde ao valor equivalente da constante, mas a coluna do índice precisa corresponder a um determinado intervalo de valores. Nessa consulta, desde que o valor da coluna key2 corresponda a qualquer um dos três intervalos a seguir, a correspondência é bem-sucedida:

  • O valor de key2 é 5555
  • O valor de key2 é 6666
  • O valor de key2 está entre 1234 e 1235

O MySQL chama esse método de acesso usando índices para correspondência de intervalo:range

2.6 índice

mysql> select key_part1,key_part2,key_part3 from demo8  where key_part2 = 'd22de';
+-----------+-----------+-----------+
| key_part1 | key_part2 | key_part3 |
+-----------+-----------+-----------+
| 99f8      | d22de     | 283e92    |
+-----------+-----------+-----------+
1 row in set (0.01 sec)

key_part2 não é a coluna de índice mais à esquerda do índice conjunto idx_key_part, portanto, não podemos usar o método de acesso ref ou range para executar esta instrução. Mas essa consulta atende às duas condições a seguir:

  • Sua lista de consulta possui apenas 3 colunas: key_part1, key_part2, key_part3 e o índice idx_key_part contém essas três colunas
  • Há apenas a coluna key_part2 na condição de pesquisa, esta coluna também está incluída no índice idx_key_part

Você pode comparar diretamente a condição key_part2 = 'd22de' percorrendo os registros do nó folha do índice idx_key_part e adicionar os valores de coluna key_part1, key_part2 e key_part3 dos registros de índice secundário correspondidos com sucesso diretamente ao conjunto de resultados. Como os registros de índice secundário são muito menores do que os registros de índice agrupados (os registros de índice agrupados armazenam todas as colunas definidas pelo usuário e as chamadas colunas ocultas, enquanto os registros de índice secundário precisam apenas armazenar as colunas de índice e as chaves primárias), e esse processo não precisa executar operações de retorno de tabela, portanto, o custo de percorrer diretamente o índice secundário é muito menor do que percorrer diretamente o índice clusterizado. Esse método de percorrer os registros do índice secundário é chamado:index

2.7 todos

mysql> select * from demo8;

Assim como esta instrução SQL, consulte todos os dados. Este método de execução de consulta é uma verificação completa da tabela. Para uma tabela InnoDB, é uma verificação direta do índice clusterizado. Esse método de execução de uma consulta usando uma verificação completa da tabela é chamado: all

3. Assuntos que precisam de atenção

3.1 Revise o índice secundário + tabela de retorno

Em geral, apenas um único índice secundário pode ser usado para executar consultas, como a seguinte instrução:

mysql> select * from demo8 where key1='00' and key2>15544;

O otimizador de consulta reconhecerá duas condições de pesquisa nesta consulta

  • chave1='00'
  • chave2>15544

O otimizador geralmente julga qual condição usar para consultar e escanear menos linhas no índice secundário correspondente com base nos dados estatísticos da tabela demo8 e seleciona a condição com menos linhas escaneadas para consultar no índice secundário correspondente. Em seguida, retorne os resultados consultados do índice secundário para a tabela para obter registros de usuário completos e, em seguida, filtre os registros de acordo com as condições where restantes. Supondo que o otimizador decida usar o índice idx_key1 para consulta, todo o processo de consulta pode ser dividido em duas etapas:

  • Passo 1: Use o índice secundário para localizar registros: encontre o registro de índice secundário correspondente da árvore B+ representada pelo índice idx_key1 de acordo com a condição key1 = '00'
  • Etapa 2: Retorne à tabela de acordo com o valor da chave primária do registro encontrado na etapa anterior, ou seja, encontre o registro completo do usuário correspondente no índice clusterizado e continue a filtrar o registro completo do usuário de acordo com a chave de condição2 >15544. Retornar os registros que finalmente atendem aos critérios do filtro para o usuário

Como os registros nos nós do índice secundário contêm apenas colunas de índice e chaves primárias, somente as condições de pesquisa relacionadas à coluna key1 serão usadas ao usar o índice idx_key1 para consultar na etapa 1 e as outras condições, como key2 > 9988, estão na etapa Não é usado em 1. Você pode continuar a filtrar os registros completos do usuário somente depois que a operação de retorno da tabela for concluída na etapa 2.

Dicas:
Deve-se notar que o que estamos falando aqui é a situação geral. Em geral, apenas um único índice secundário será usado para executar uma consulta

3.2 Esclarecer o intervalo de alcance usado pelo método de acesso ao alcance

Para o índice da árvore B+, desde que a coluna do índice e a constante usem =, <=>, in, not in, is null, not null, >, <, >=, <=, between, != (diferente para Escrito como <>) ou conectado com operadores semelhantes, um chamado intervalo pode ser gerado.

dica:

  • O operador like é especial e só pode usar o índice ao corresponder à string completa ou ao prefixo da string.
  • O efeito do operador in é o mesmo que a conexão entre =vários operadores correspondentes equivalentes, ou seja, serão gerados vários intervalos de ponto único. Por exemplo, os efeitos das duas instruções a seguir são os mesmos: select * from demo8 onde key2 em (1222, 1333); selecione * de demo8 onde key2 = 1222 ou key2 = 1333;or

No entanto, no trabalho normal, a cláusula where de uma consulta pode ter muitas condições de pesquisa pequenas, e essas condições de pesquisa precisam ser conectadas usando os operadores e ou ou:

  • A e B, ambos A e B são verdadeiros, toda a expressão é verdadeira
  • A ou B, se A ou B for verdadeiro, toda a expressão é verdadeira

Quando queremos usar o método de acesso por intervalo para executar uma instrução de consulta, o ponto principal é descobrir os índices disponíveis para a consulta e os intervalos de intervalo correspondentes a esses índices. Vejamos como extrair o intervalo de intervalo correto das condições de pesquisa complexas compostas por e ou ou nos dois casos a seguir:

3.2.1 Todas as condições de pesquisa podem usar um índice

mysql> select * from demo8 where key2 > 2222 and key2 > 3333;

Todas as condições de pesquisa nesta consulta podem usar a chave2, ou seja, cada condição de pesquisa corresponde a um intervalo de intervalo de idx_key2. Essas duas pequenas condições de pesquisa são conectadas usando AND, ou seja, a interseção de dois intervalos de alcance é tomada. A interseção de key2 > 2222 e key2 > 3333 é obviamente key2 > 3333. O intervalo da consulta acima usando idx_key2 é (3333, +∞)

se é ou

mysql> select * from demo8 where key2 > 2222 or key2 > 3333;

ou significa que a união de cada intervalo de intervalo precisa ser obtida. A união de key2 > 2222 e key2 > 3333 é key2 > 2222. O intervalo de intervalo usando idx_key2 na consulta acima é (2222, +∞)

3.2.2 Algumas condições de pesquisa não podem usar o índice

mysql> select * from demo8 where key2 > 2222 AND common_field = '039cb00';

O índice que pode ser usado nesta instrução de consulta é apenas idx_key2 e o registro do índice secundário de idx_key2 não contém o campo common_field, portanto, a condição de common_field = '039cb00' não é usada no estágio de uso do índice secundário idx_key2 para localizar registros. Essa condição é utilizada após retornar a tabela para obter registros completos do usuário, e o intervalo de intervalo é para o conceito proposto no índice buscar registros, portanto a condição de common_field = '039cb00' não precisa ser considerados ao determinar o intervalo de intervalo. Quando determinamos o intervalo de intervalo para um índice, precisamos apenas substituir as condições de pesquisa que não usam o índice relevante por verdadeiro (substitua as condições de pesquisa que não usam o índice por verdadeiro, porque não pretendo usar essas condições para pesquisar o índice Portanto, independentemente de os registros no índice atenderem a essas condições ou não, iremos selecioná-los e usá-los para filtrar ao retornar à tabela posteriormente).

mysql> select * from demo8 where key2 > 2222 AND true;

simplificado

mysql> select * from demo8 where key2 > 2222;

A partir disso, pode-se obter que o intervalo de uso de idx_key2 é: (2222, +∞). Da mesma forma, a situação de uso ou pode ser obtida:

mysql> select * from demo8 where key2 > 2222 or common_field = '039cb00';

mysql> select * from demo8 where key2 > 2222 or true;

mysql> select * from demo8 where true;

Isso também mostra que se você for forçado a usar idx_key2 para executar a consulta, o intervalo correspondente é (-∞, +∞), ou seja, você precisa retornar todos os registros do índice secundário para a tabela. Esse custo é definitivamente maior do que a varredura direta da tabela completa. Ou seja, se uma condição de pesquisa que usa o índice estiver conectada a uma condição de pesquisa que não usa o índice usando ou, o índice não pode ser usado.

3.2.3 Encontre o intervalo de correspondência de intervalo sob condições de pesquisa complexas

mysql> select * from demo8 
	where (key1 > 'ed' and key2 = 66 ) 
	or (key1 < 'zc' and key1 > 'zz') 
	or (key1 like '%33' and key1 > 'fa' and (key2 < 7777 or common_field = '97d435e')) ;

Não entre em pânico ao ver SQL com condições tão complexas, vamos analisá-lo lentamente

Etapa 1: primeiro verifique quais colunas estão envolvidas nas condições de pesquisa na cláusula where e quais colunas podem usar índices

As condições de pesquisa desta consulta envolvem as três colunas de key1, key2 e common_field e, em seguida, a coluna key1 possui um índice secundário comum idx_key1 e a coluna key2 possui um índice secundário idx_key2 exclusivo

Passo 2: Para aqueles índices que podem ser usados, analise seus intervalos de alcance

Etapa 3: suponha que usamos idx_key1 para executar a consulta ou use o método acima, remova temporariamente as condições de pesquisa que não usam o índice

(key1 > 'ed' and true ) or(key1 < 'zc' and key1 > 'zz') or(true and key1 > 'fa' and (true or true))

continuar a simplificar

(key1 > 'ed') OR(key1 < 'zc' AND key1 > 'zz') OR(key1 > 'fa')

Etapa 4: substitua a condição que é sempre verdadeira ou falsa

mysql> select 'zc' > 'zz';
+-------------+
| 'zc' > 'zz' |
+-------------+
|           0 |
+-------------+
1 row in set (0.00 sec)

O resultado é 0, que é falso, 'zc' é menor que 'zz'. A correspondência de key1 < 'zc' AND key1 > 'zz' é sempre falsa, portanto, a condição de pesquisa acima pode ser escrita assim:
(key1 > 'ed') OR (key1 > 'fa')

Continue a simplificar o intervalo

mysql> select 'ed' > 'fa';
+-------------+
| 'ed' > 'fa' |
+-------------+
|           0 |
+-------------+
1 row in set (0.00 sec)

O operador or entre key1 > 'ed' e key1 > 'fa' é usado para conectar, o que significa fazer uma união, então o intervalo para o qual o resultado final é simplificado é: key1 > 'ed'. Ou seja: se a instrução de consulta das condições de pesquisa complexas acima usar o índice idx_key1 para executar a consulta, é necessário extrair todos os registros de índice secundário que satisfaçam key1 > 'ed' e, em seguida, retornar à tabela com o id desses registros para obter registros de usuário completos e, em seguida, usar outros critérios de pesquisa para filtrar.

Passo 5: Supondo que usamos idx_key2 para executar a consulta, precisamos substituir temporariamente aquelas condições de pesquisa que não usam o índice pela condição trueE, e as condições de pesquisa relacionadas a key1 e common_field precisam ser substituídas

(true and key2 = 66 ) or(true and true) or(true and true and (key2 < 7777 or true))

O resultado de key2 < 7777 OU verdadeiro é verdadeiro, continue a simplificar

key2 = 66 or true

Continuar a simplificar: verdadeiro

Esse resultado significa que, se quisermos usar o índice idx_key2 para executar a instrução de consulta, precisamos verificar todos os registros do índice secundário idx_key2 e retornar à tabela. Em comparação com o uso do índice secundário idx_key1, o ganho supera o ganho , e os resultados da comparação dos dois métodos não serão usados ​​como índice idx_key2.

4. Mesclagem de índice

No MySQL, muitos recursos de otimização são oficialmente incorporados para nós. Se precisamos ativá-los ou não, é necessário configurá-los manualmente:

mysql> show variables like 'optimizer_switch'\g
*************************** 1. row ***************************
variable_name: optimizer_switch
        value: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off,skip_scan=on,hash_join=on,subquery_to_derived=off,prefer_ordering_index=on,hypergraph_optimizer=off,derived_condition_pushdown=on
1 row in set (0.01 sec)

Vamos explicar resumidamente:

  • index_merge=on (mesclagem de índice)
  • index_merge_union=on (Union index merge—união de valores de id obtidos por índices não agrupados)
  • index_merge_sort_union=on (Mesclagem de índice Sort-Union - o valor de id obtido pelo índice não clusterizado é classificado primeiro - pegue a união)
  • index_merge_intersection=on (Mesclagem de índice de interseção - a interseção de valores de id obtidos por índices não agrupados)
  • engine_condition_pushdown=on (engine condition pushdown - usado apenas para o mecanismo NDB, quando ativado, os dados filtrados de acordo com a condição WHERE são enviados para o nó SQL para processamento e os dados de todos os nós de dados não são ativados para serem enviados ao SQL nó para processamento.)
  • index_condition_pushdown=on (pushdown de condição de índice—ICP)
  • mrr=on (Multi-Range Read-MRR - o principal objetivo dessa otimização é usar a leitura de disco sequencial o máximo possível)
  • mrr_cost_based=on (escolha baseada em custo - se o cálculo é baseado no cálculo de custo/consumo de julgamento usando MRR)
  • block_nested_loop=on (junção de loop aninhado baseada em bloco - BNL)
  • batched_key_access=off (BKA — otimização para o algoritmo Index Nested-Loop Join (NLJ))
  • materialização=on (materialização)
  • subquery_materialization_cost_based=on (se habilitar o cálculo de custo da materialização da subconsulta)
  • semijoin=on (semi junção)
  • loosescan=on (semi-junção - varredura solta)
  • firstmatch=on (semi join - primeira partida)
  • duplicadoweedout=on (semi-join - eliminação de valor duplicado)
  • use_index_extensions=on (use extensões de índice)
  • condition_fanout_filter=on (filtragem condicional (fanout))
  • derivado_merge=on (visualização/mescla de tabela derivada, precisa cooperar com Auto_key)

Esses recursos de otimização serão implementados lentamente em detalhes em artigos posteriores. De volta ao conteúdo de hoje, dissemos anteriormente que o MySQL usa apenas um único índice secundário no máximo ao executar uma consulta em circunstâncias normais, mas em alguns casos especiais também é possível usar vários índices secundários em uma consulta. O MySQL chama esse método de execução de usar vários índices para concluir uma consulta: mesclagem de índice, que é o recurso de otimização que classifica no topo. Especificamente, existem três tipos de algoritmos de mesclagem de índice:

4.1 Mesclagem de interseção

A tradução literal de Interseção é interseção. Isso significa que uma determinada consulta pode usar vários índices secundários e os resultados consultados de vários índices secundários serão cruzados.

mysql> select * from demo8 where key1='4a' AND key3='c84';

Se esta consulta for executada usando a mesclagem de interseção, o processo será o seguinte:

  • Retire o registro relacionado de key1 = '4a' da árvore B+ correspondente ao índice secundário idx_key1.
  • Retire os registros relevantes de key3 = 'c84' da árvore B+ correspondente ao índice secundário idx_key3.
  • Os registros do índice secundário são compostos por coluna de índice + chave primária, assim podemos calcular a interseção dos valores de id nos dois conjuntos de resultados.
  • Retorne à tabela de acordo com a lista de valores de id gerada na etapa anterior, ou seja, retire o registro do usuário completo com o valor de id especificado do índice clusterizado e retorne ao usuário.

Alguns alunos aqui pensarão: Por que não usar idx_key1 ou idx_key3 diretamente para ler um índice secundário com base em uma determinada condição de pesquisa e, em seguida, filtrar outra condição de pesquisa após retornar à tabela? Aqui está uma análise do custo entre os dois métodos de execução de consulta:

O custo de ler apenas um índice secundário:

  • Leia um índice secundário de acordo com uma determinada condição de pesquisa;
  • Retorne à tabela de acordo com o valor da chave primária obtido do índice secundário e, em seguida, filtre outras condições de pesquisa;

Pegue o custo de interseção depois de ler vários índices secundários:

  • Leia diferentes índices secundários de acordo com diferentes condições de pesquisa;
  • Pegue a interseção dos valores de chave primária obtidos de vários índices secundários e, em seguida, retorne à tabela;

Embora a leitura de vários índices secundários consuma mais desempenho do que a leitura de um índice secundário, a operação de leitura de índices secundários é de E/S sequencial, enquanto a operação de retorno à tabela é de E/S aleatória, portanto, se apenas um índice secundário for lido Ao indexar , o número de registros que precisam ser retornados à tabela é muito grande e o número de registros que são cruzados após a leitura de vários índices secundários é muito pequeno. Quando a perda de desempenho causada pelo retorno à tabela é salva em comparação com o desempenho trazido pelo acesso a múltiplos índices secundários Quando a perda é maior, é mais barato ler a interseção de múltiplos índices secundários do que ler apenas um índice secundário.

O MySQL só pode usar a mesclagem de índice de interseção em certas situações específicas:

Situação 1: A coluna do índice secundário é uma correspondência de equivalência. Para um índice conjunto, cada coluna no índice conjunto deve ser uma correspondência de equivalência e apenas parte das colunas não pode ser correspondida.

Por exemplo, a consulta a seguir pode usar os dois índices secundários idx_key1 e idx_key_part para executar a operação de mesclagem de índices de interseção:

mysql> select * from demo8 where key1 = 'a' and key_part1 = 'a' and key_part2 = 'b' and key_part3 = 'c';

As duas consultas a seguir não podem ser mescladas com índices de interseção:

mysql> select * from demo8 where key1 > 'a' and key_part1 = 'a' and key_part2 = 'b' and key_part3 = 'c';
mysql> select * from demo8 where key1 = 'a' and key_part1 = 'a';

A primeira consulta é porque a correspondência de intervalo é executada em key1 e a segunda consulta é porque a coluna key_part2 no índice conjunto idx_key_part não aparece nas condições de pesquisa, portanto, essas duas consultas não podem ser mescladas com o índice de interseção.

Caso 2: A coluna de chave primária pode ser uma correspondência de intervalo.

Por exemplo, a consulta a seguir pode usar a chave primária e idx_key1 para mesclar o índice de interseção:

mysql> select * from demo8 where id > 100 and key1 = 'a';

Para o índice secundário do InnoDB, os registros são primeiro classificados de acordo com a coluna do índice.Se o índice secundário for um índice conjunto, ele será classificado de acordo com as colunas no índice conjunto. O registro do usuário do índice secundário é composto pela coluna do índice + chave primária. Pode haver muitos registros com o mesmo valor da coluna do índice secundário, e os registros com o mesmo valor dessas colunas do índice são classificados de acordo com o valor da coluna chave primária. A mesclagem do índice de interseção só é possível quando as colunas do índice secundário são todas correspondências equivalentes, porque somente nesse caso o conjunto de resultados consultado com base no índice secundário é classificado de acordo com o valor da chave primária.

então? Ainda não entendi que o conjunto de resultados consultado com base no índice secundário é classificado de acordo com o valor da chave primária. Qual é o benefício de usar o índice de interseção para mesclar? Rapaz, não esqueça que a mesclagem do índice de interseção fará a interseção dos valores da chave primária consultados em vários índices secundários. Se o conjunto de resultados consultado de cada índice secundário já estiver classificado de acordo com a chave primária, então O processo de encontrar a interseção é muito fácil. Suponha que uma consulta use a mesclagem de índices de interseção para obter os valores da chave primária dos dois índices secundários idx_key1 e idx_key2 respectivamente:

  • Obtenha os valores de chave primária classificados de idx_key1: 1, 3, 5
  • Obtenha os valores de chave primária classificados de idx_key2: 2, 3, 4

Então o processo de encontrar a interseção é assim: retire o menor valor da chave primária nos dois conjuntos de resultados um a um, se os dois valores forem iguais, adicione-o ao resultado final da interseção, caso contrário, descarte o primário menor atual valor da chave primária e, em seguida, pegue o valor descartado Compare o último valor da chave primária do conjunto de resultados onde o valor da chave primária está localizado até que o valor da chave primária em um determinado conjunto de resultados seja usado. Se você ainda não entender, continue para ler:

  • Primeiro, retire o menor valor de chave primária dos dois conjuntos de resultados para comparação, porque 1 < 2, então descarte o valor de chave primária 1 do conjunto de resultados de idx_key1 e retire os últimos 3 para comparação.
  • Como 3 > 2, o valor da chave primária 2 do conjunto de resultados de idx_key2 é descartado e o último 3 é retirado para comparação.
  • Como 3 = 3, adicione 3 ao resultado final da interseção e continue a comparar os valores da chave primária por trás dos dois conjuntos de resultados.
  • Os seguintes valores de chave primária também não são iguais, então apenas o valor de chave primária 3 é incluído no resultado final da interseção.

Apesar da complexidade do que escrevemos, na verdade, esse processo é muito rápido e a complexidade de tempo é O(n), mas se o conjunto de resultados consultado de cada índice secundário não for classificado pela chave primária, o resultado deve first be Depois que os valores da chave primária centralizada forem classificados, será demorado fazer o processo acima.

Dica:
Existe um termo apropriado para recuperar registros da tabela de acordo com o valor ordenado da chave primária, chamado: Rowid Ordered Retrieval, ou ROR para abreviar, e você estará familiarizado com este termo quando o vir em alguns lugares no futuro .

Além disso, não apenas a mesclagem de índice de interseção pode ser usada entre vários índices secundários, mas o índice de cluster também pode participar da mesclagem de índice.Usar mesclagem de índice de
interseção mesclagem de índice. Por que a chave primária pode ter correspondência de intervalo? Ainda é preciso voltar ao cenário de aplicação, por exemplo, veja a seguinte consulta:

mysql> select * from demo8 where key1 = 'a' and id > 100;

Assumindo que esta consulta pode ser mesclada usando o índice Intersection, tomamos como certo que esta consulta obterá alguns registros do índice clusterizado de acordo com a condição de id > 100 e obterá alguns registros do índice secundário idx_key1 através da condição de key1 = 'a' e, em seguida, encontre a interseção.Na verdade, isso complica o problema e não há necessidade de obter um registro do índice clusterizado. Não se esqueça de que todos os registros do índice secundário têm valores de chave primária, então você pode executar diretamente o filtro id da condição > 100 no valor da chave primária obtido de idx_key1, é tão simples. Portanto, a condição de busca envolvendo a chave primária é apenas para
filtrar registros do conjunto de resultados obtidos de outros índices secundários, não importando se é uma correspondência equivalente ou não.

Obviamente, os casos 1 e 2 mencionados acima são apenas condições necessárias para que ocorra a fusão do índice de interseção, mas não são condições suficientes. Mesmo que o Caso 1 e o Caso 2 sejam verdadeiros, a mesclagem do índice de interseção pode não ocorrer necessariamente e, em última análise, depende de como o otimizador escolhe. O otimizador usará a mesclagem de índice de interseção somente quando o número de registros obtidos de um índice secundário baseado apenas nas condições de pesquisa for muito grande, resultando em muito custo de retorno à tabela e o número de registros que precisam ser retornados para a tabela após a fusão através do índice de interseção é bastante reduzido.

4.2 Fusão Sindical

Quando escrevemos uma declaração de consulta, geralmente queremos retirar os registros que atendem a uma determinada condição de pesquisa e também os registros que atendem a outra condição de pesquisa.Dizemos que existe uma relação OU entre essas diferentes condições de pesquisa. Às vezes, diferentes condições de pesquisa do relacionamento OR usam índices diferentes, por exemplo:

mysql> select * from demo8 where key1 < 'a' or key3 > 'z';

Interseção significa interseção, que é aplicável ao caso em que condições de pesquisa usando índices diferentes são conectadas por e; União é o significado de união, aplicável ao caso em que condições de pesquisa usando índices diferentes são conectadas por ou. Semelhante à mesclagem de índice de interseção, o MySQL só pode usar a mesclagem de índice de união em determinadas circunstâncias:

Situação 1: As colunas do índice secundário são correspondência de equivalência.Para o índice conjunto, cada coluna no índice conjunto deve ser correspondência de equivalência e apenas algumas das colunas correspondentes não podem aparecer.

Por exemplo, a consulta abaixo pode usar dois índices secundários, idx_key1 e idx_key_part, para mesclar os índices Union:

mysql> select * from demo8 where key1 = 'a' or ( key_part1 = 'a' and key_part2 = 'b' and key_part3 = 'c');

No entanto, as duas consultas a seguir não podem ser mescladas com índices de União:

mysql> select * from demo8 where key1 > 'a' or (key_part1 = 'a' and key_part2 = 'b' and key_part3 = 'c');
mysql> select * from demo8 where key1 = 'a' or key_part1 = 'a';

A primeira consulta é porque a correspondência de intervalo é executada em key1 e a segunda consulta é porque a coluna key_part2 no índice conjunto idx_key_part não aparece nas condições de pesquisa, portanto, essas duas consultas não podem ser mescladas com o índice Union.
Caso 2: A coluna de chave primária pode ser uma correspondência de intervalo.
Caso 3: Use a condição de pesquisa mesclada pelo índice de interseção (na verdade, essa situação é bem fácil de entender, ou seja, algumas partes da condição de pesquisa são cruzadas pelo conjunto de chaves primárias obtido pela mesclagem do índice de interseção e pelo conjunto de chaves primárias obtido por Outros métodos).

Na verdade, essa situação é bastante fácil de entender, ou seja, algumas partes da condição de pesquisa usam a Intersectioninterseção do conjunto de chaves primárias obtido pela mesclagem de índices e o conjunto de chaves primárias obtido por outros métodos, como esta consulta:

mysql> select * from single_table where key_part1 = 'a' and key_part2 = 'b' and key_part3 = 'c' or (key1 = 'a' and key3 = 'b');

O otimizador pode executar esta consulta desta maneira:

  • Primeiro, de acordo com a condição de pesquisa key1 = 'a' AND key3 = 'b', o conjunto de chaves primárias é obtido mesclando os índices idx_key1 e idx_key3 usando o índice Intersection.
  • Então, de acordo com a condição de pesquisa key_part1 = 'a' AND key_part2 = 'b' AND key_part3 = 'c' obtenha outro conjunto de chaves primárias do índice conjunto idx_key_part.
  • Mesclar os dois conjuntos de chaves primárias acima por meio da mesclagem de índice de união e, em seguida, retornar à tabela e retornar o resultado ao usuário

É claro que, se as condições da consulta atenderem a essas condições, a fusão do índice Union pode não ser necessariamente adotada. No final, ainda depende de como o otimizador escolher. O otimizador usará a mesclagem do índice Union somente quando o número de registros obtidos de um índice secundário baseado apenas nas condições de pesquisa for relativamente pequeno e o custo de acesso por meio da mesclagem do índice Union for menor do que o de uma varredura completa da tabela.

4.3 Mesclagem Sort-Union

As condições de uso da fusão do índice Union são muito rígidas e é necessário garantir que cada coluna do índice secundário possa ser usada sob a condição de correspondência equivalente. Por exemplo, a consulta a seguir não pode usar a mesclagem de índice de União:

mysql> select * from demo8 where key1 < 'a' and key3 > 'z';

Isso ocorre porque os valores de chave primária dos registros de índice secundário obtidos do índice idx_key1 de acordo com key1 < 'a' não são classificados e os valores de chave primária dos registros de índice secundário obtidos do índice idx_key3 de acordo com key3 > 'z' Os valores-chave não são classificados, mas as duas condições de key1 < 'a' e key3 > 'z' são particularmente tentadoras para nós, então podemos fazer isso:

  • Primeiro obtenha registros do índice secundário idx_key1 de acordo com a condição key1 < 'a' e classifique de acordo com o valor da chave primária dos registros
  • De acordo com a condição key3 > 'z', os registros são sempre obtidos do índice secundário idx_key3 e classificados de acordo com o valor da chave primária dos registros
  • Como os valores da chave primária dos dois índices secundários acima são classificados, as operações restantes são as mesmas do método de mesclagem do índice Union

Primeiro classificamos o acima de acordo com os valores da chave primária registrados no índice secundário e, em seguida, executamos de acordo com o método de mesclagem do índice Union, que é chamado de mesclagem do índice Sort-Union. é um passo a mais do que a simples mesclagem de índice de união O processo de classificação dos valores de chave primária de registros de índice secundário.

Dica:
Por que não há mesclagem de índice Sort-Intersection quando há uma mesclagem de índice Sort-Union? Sim, de fato não existe fusão de índice Sort-Intersection. O cenário aplicável de Sort-Union é que o número de registros obtidos de um índice secundário com base apenas nos critérios de pesquisa é relativamente pequeno, de modo que o custo de classificação desses registros de índice secundário de acordo com o valor da chave primária não seja muito alto. O cenário aplicável para mesclar o índice de interseção é que muitos registros são obtidos de um índice secundário com base apenas nos critérios de pesquisa, resultando em muita sobrecarga para retornar à tabela. Após a mesclagem, a sobrecarga para retornar à tabela pode ser significativamente reduzido, mas se Sort-Intersection for adicionado, é necessário classificar um grande número de registros de índice secundário de acordo com o valor da chave primária. Esse custo pode ser maior do que o de consultar a tabela, então Sort-Intersection não é introduzido .

4.4 Notas sobre fusão conjunta de índices

Índice de junção em vez de mesclagem de índice de interseção

mysql> select * from demo8 where key1 = 'a' and key3 = 'b';

A razão pela qual esta consulta pode ser executada combinando o índice de interseção não é porque idx_key1 e idx_key3 são dois índices de árvore B+ separados. Se você criar um índice conjunto para essas duas colunas, use esse índice conjunto diretamente para fazer as coisas. Agora, por que se preocupar em mesclar com qualquer índice, assim:

mysql> alter table demo8 drop index idx_key1, idx_key3, add index idx_key1_key3(key1, key3);

Dessa forma, nos livramos dos inúteis idx_key1 e idx_key3 e, em seguida, adicionamos um índice conjunto idx_key1_key3. Usar esse índice conjunto para consultar é simplesmente rápido e bom. Não há necessidade de ler uma árvore B+ extra ou mesclar os resultados. Por quê não para?

Dica:
Mas tenha cuidado, pois existem cenários de negócios em que a coluna key3 é consultada separadamente, portanto, você deve adicionar o índice separado da coluna key3

Resumir

Hoje, aprendi sobre o método de acesso do MySQL para uma única tabela e a otimização recurso-índice mesclado. Vamos resumir abaixo:

  • Método de acesso para tabela única:

    • const: O método de acesso para localizar um registro por meio da chave primária ou da coluna de índice secundário exclusivo é definido como: const, que significa nível constante, e o custo é insignificante.
    • ref: A condição de busca é comparar o valor equivalente da coluna do índice secundário com uma constante.O método de acesso que utiliza o índice secundário para executar a consulta chama-se: ref.
    • ref_or_null: Quando a consulta é executada usando um índice secundário em vez de uma varredura completa da tabela, o método de acesso usado por esse tipo de consulta é chamado: ref_or_null.
    • range: O método de acesso que usa o índice para correspondência de intervalo é chamado de: range.
    • index: O método de execução de percorrer registros de índice secundário é chamado de: index.
    • all: O método de execução de uma consulta usando uma varredura completa da tabela é chamado de: all.
  • Três algoritmos para mesclagem de índice:

    • Mesclagem de interseção (index_merge_intersection).
    • Mesclagem de união (index_merge_union).
    • Mesclagem Sort-Union (index_merge_sort_union).

Também aprendemos que as condições de disparo dos três algoritmos para mesclagem de índices são necessárias e insuficientes. Se os algoritmos relevantes serão usados ​​no final, ainda precisa ser julgado pelo otimizador. Ao mesmo tempo, também aprendi o intervalo de intervalo usado pelo método de acesso de intervalo e estimei o custo de execução do SQL usando diferentes índices por meio de análise artificial. O conteúdo de hoje é mais baseado em princípios, mas é muito simples de entender.Você deve combinar o conhecimento anterior do índice da árvore MySQL B+ para sentir a sutileza do design do MySQL.

Até agora, o estudo de hoje acabou, espero que você se torne um eu indestrutível
~~~

Você não pode ligar os pontos olhando para frente; você só pode conectá-los olhando para trás. Portanto, você precisa confiar que os pontos de alguma forma se conectarão em seu futuro. Você precisa confiar em algo - seu instinto, destino, vida, karma, seja o que for. Essa abordagem nunca me decepcionou e fez toda a diferença na minha vida

Se meu conteúdo for útil para você, por favor 点赞, criar não é fácil, o apoio de todos é a 评论motivação 收藏para eu perseverar

insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/liang921119/article/details/130707882
Recomendado
Clasificación