Медленный MySQL (InnoDB) запрос несмотря на соединение по индексированному ключу, почему? - PullRequest
1 голос
/ 17 августа 2011

Есть ли у вас идеи, почему этот запрос может быть медленным (1,7 с на быстром в противном случае сервере MySQL):

SELECT DISTINCT TABLE_A.keyA 
FROM TABLE_A,TABLE_B 
WHERE TABLE_A.keyB= TABLE_B.keyB 
AND TABLE_A.fieldC in (0,2,5,7,8) LIMIT 20;

С этим планом выполнения, заданным EXPLAIN:

id    select_type table       type    possible_keys         key                   key_len   ref     rows     Extra 
1     SIMPLE      TABLE_B     index   PRIMARY               PRIMARY               8     NULL      10     Using index; Using temporary
1     SIMPLE      TABLE_A     ref     IDX_TABLE_A_KEY_B     IDX_TABLE_A_KEY_B     8     TABLE_B.keyB     25455     Using where

Другие элементы:

  • таблица TABLE_A имеет 300 000 строк
  • TABLE_A.keyA является первичным ключом TABLE_A
  • TABLE_A.keyB - это внешний ключ к первичному ключу B из TABLE_B; таблица TABLE_B имеет 10 строк;
  • 99% TABLE_A имеет fieldC = 1, а 1% таблицы имеет fieldC в (0,2,5,7,8) (поэтому это поле не проиндексировано; EDIT это предложение не вызывает проблем, поскольку SELECT с тем же предложением, но нет соединения с TABLE_B быстро);
  • мне кажется, что виноват именно JOIN, потому что простой SELECT на столе быстрый;
  • соединение с другой таблицей TABLE_C также очень медленное;
  • Версия MySQL: 5.1.23a-maria-alpha

У вас есть идеи?

Ответы [ 5 ]

5 голосов
/ 17 августа 2011

99% TABLE_A имеет fieldC = 1, а 1% таблицы имеет fieldC in (0,2,5,7,8) (поэтому это поле не индексируется

Это было бы отличной причиной для индексации столбца. Вашему запросу требуется только менее 1% таблицы, поэтому индекс будет очень избирательным.

2 голосов
/ 17 августа 2011

Вероятно, предложение IN, они, как правило, довольно медленные, у вас есть индекс по TABLE_A.fieldC?

0 голосов
/ 17 августа 2011

Добавить индекс в столбце fieldC.Затем выполните запрос

Select DISTINCT keyA from 
 (select keyA, keyB from TABLE_A where fieldC in (0,2,5,7,8)) 
as temp STRAIGHT_JOIN TABLE_B on temp.keyB=TABLE_B.keyB limit 20

Попробуйте с прямым соединением и внутренним соединением.

0 голосов
/ 17 августа 2011

попробуй

SELECT DISTINCT TABLE_A.keyA 
FROM TABLE_A
WHERE TABLE_A.keyB IN (SELECT TABLE_B.keyB FROM TABLE_B )
AND TABLE_A.fieldC in (0,2,5,7,8) LIMIT 20;
0 голосов
/ 17 августа 2011
SELECT DISTINCT TABLE_A.keyA 
FROM TABLE_A 
INNER JOIN TABLE_B ON TABLE_A.keyB = TABLE_B.keyB 
WHERE 
TABLE_A.fieldC IN (0, 2, 5, 7, 8) LIMIT 20;

Попробуйте это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...