Выберите в 10 раз медленнее при изменении порядка - PullRequest
9 голосов
/ 16 июня 2011

Зачем это выбирать, назовите его A , (0.02406s):

select * from char_kills
where rid_first <= 110 and rid_last >= 110
order by kills desc
limit 500;

будет в 10 раз медленнее, чем при изменении порядка сортировки, назовите его B , (0,00229 с):

select * from char_kills
where rid_first <= 110 and rid_last >= 110
order by kills
limit 500;

а как ты мог оптимизировать А? Использование таблиц InnoDB в MySQL 5.5.


Дополнительная информация приведена ниже.

describe char_kills;

cid, int(10) unsigned, NO, PRI, , 
rid_first, int(10) unsigned, NO, PRI, , 
rid_last, int(10) unsigned, NO, PRI, , 
kills, int(11), NO, PRI, , 
offi_rank, smallint(5) unsigned, YES, , , 

select count(*) from char_kills;

146312

select count(*) from char_kills where rid_first <= 110 and rid_last >= 110;

7207

show indexes from char_kills;

char_kills, 0, PRIMARY, 1, kills, A, 160711, , , , BTREE, , 
char_kills, 0, PRIMARY, 2, rid_first, A, 160711, , , , BTREE, , 
char_kills, 0, PRIMARY, 3, rid_last, A, 160711, , , , BTREE, , 
char_kills, 0, PRIMARY, 4, cid, A, 160711, , , , BTREE, , 

A

Explain:
1, SIMPLE, char_kills, index, , PRIMARY, 16, , 500, Using where

Profiling:
0.02406750, select * from char_kills where rid_first <= 110 and rid_last >= 110 order by kills desc limit 500

starting, 0.000050
checking permissions, 0.000007
Opening tables, 0.000029
System lock, 0.000008
init, 0.000022
optimizing, 0.000008
statistics, 0.000013
preparing, 0.000012
executing, 0.000003
Sorting result, 0.000006
Sending data, 0.023822
end, 0.000007
query end, 0.000004
closing tables, 0.000015
freeing items, 0.000058
logging slow query, 0.000002
cleaning up, 0.000004

B

Explain:
1, SIMPLE, char_kills, index, , PRIMARY, 16, , 500, Using where

Profiling:
0.00229975, select * from char_kills where rid_first <= 110 and rid_last >= 110 order by kills limit 500

starting, 0.000049
checking permissions, 0.000007
Opening tables, 0.000027
System lock, 0.000008
init, 0.000019
optimizing, 0.000008
statistics, 0.000012
preparing, 0.000009
executing, 0.000003
Sorting result, 0.000004
Sending data, 0.002091
end, 0.000004
query end, 0.000003
closing tables, 0.000010
freeing items, 0.000042
logging slow query, 0.000002
cleaning up, 0.000003

Больше перестановок

Slow:

where rid_first <= 110 and rid_last >= 110 order by kills desc limit 500; -- 0.031s, A, 7k matching rows
where rid_first >= 110 and rid_last <= 110 order by kills      limit 500; -- 0.094s, 449 rows

Быстро:

where rid_first <= 110 and rid_last >= 110 order by kills      limit 500; -- 0.000s, B
where rid_first <= 110 and rid_last <= 110 order by kills      limit 500; -- 0.000s
where rid_first >= 110 and rid_last >= 110 order by kills desc limit 500; -- 0.000s
where rid_first <= 110 and rid_last <= 110 order by kills desc limit 500; -- 0.000s
where rid_first <= 110 and rid_last <= 110 order by kills desc limit 500; -- 0.000s
where rid_first <= 110                     order by kills desc limit 500; -- 0.000s
where                      rid_last >= 110 order by kills desc limit 500; -- 0.000s

1 Ответ

1 голос
/ 16 июня 2011

Ответ на вопрос, почему это происходит, довольно глуп (и очевиден при большом времени отправки данных проблемного запроса):

Изобразите свою базу данных (которая хранится в виде файла, как вы, вероятно, знаете) какбольшое прямоугольное кукурузное поле, и вы стоите перед ним.Если вы хотите собирать кукурузу в планах кукурузы, которые расположены в 4 углах кукурузного поля, очевидно, что будет медленнее (потому что вам нужно далеко ходить), чем собирать кукурузу с кукурузных растений перед вами.

В компьютерах, поскольку (во всем) значение имеет расстояние, и оно выражается в задержке ввода-вывода (и «пропускает» поиск ожидаемой информации где-либо).

Таким образом, причина медлительности заключается в том, что: a) проблемный запросслучается, что нужно читать данные со всего файла (а не последовательные чтения, как это делает быстрый запрос)

b) вы недавно не дефрагментировали свою базу данных

c) индексирование выполняется неуместноопределены

РЕДАКТИРОВАТЬ : Чтобы было ясно, запросы находят нужные записи почти так же быстро, поэтому проблема не в индексации или ее определении (по крайней мере, не самой большой, попробуйте сделатьмногостолбцовый индекс, включающий все ваши столбцы только для проверки), но когда запрос говорит: «Хорошо, я знаю, где все находится сейчас, позвольте мне взять его для отображенияing "<- этот процесс извлечения убивает одного из них. </p>

...