MySql - Оптимизировать запрос

SQL во всех проявлениях - от ANSI-92 до TSQL.

Модераторы: Yurich, Absurd

Ответить
UUU
Сообщения: 310
Зарегистрирован: 17 фев 2004, 09:27
Откуда: Иваново
Контактная информация:

Наверное, лучше было написать в тему о халяве :-) Но все же:
есть запрос

Код: Выделить всё

select 
 s_in.id,
 s_in.saddr,
 elt((direction.Number=s_in.daddr)+1,concat(direction.Number_to,'\ ',SUBSTRING_INDEX(s_in.daddr,'\ ',-1)),direction.Number_to),
 s_in.s,
 direction.script,
 direction.pass,
 direction.All,
 direction.MaxCount,
 (unix_timestamp(s_in.DateTime_web)-unix_timestamp(s_in.DateTime_in))/300 
from s_in,direction 
where 
 s_in.DateTime_web<=Now() 
 and s_in.status<'200' 
 and s_in.status<>'230'
 and direction.Number=SUBSTRING_INDEX(s_in.daddr,'\ ',1) 
order by datetime_web 
Как бы его с оптимизировать, и какие индексы для этого лучше создать.
Буду премного благодарен.
Аватара пользователя
AiK
Сообщения: 2287
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

Индексы просятся на status и Number.
Условие для DateTime_web выглядит подозрительным.
and direction.Number=SUBSTRING_INDEX(s_in.daddr,'\ ',1)
Тоже не быстрая конструкция. Всегда предпочтительнее все Join'ы делать по связкам PK-FK.
Даже самый дурацкий замысел можно воплотить мастерски
UUU
Сообщения: 310
Зарегистрирован: 17 фев 2004, 09:27
Откуда: Иваново
Контактная информация:

Спасибо.
Нашел одно лишнее условие

Код: Выделить всё

 and s_in.status<>'230'
:-)
Но вчера ставил эксперименты. Делал в цикле разные выборки, которые встречаются в коде, чтобы посмотреть, на что тратится время. Делал 10000 запросов и оказалось, что приведенная конструкция тратила около 3 секунд, а вот конструкция

Код: Выделить всё

 
select q,w,e,r,t,y,u,i from my_table where 1 limit 1

выполнялась раза в 3 дольше.
Аватара пользователя
AiK
Сообщения: 2287
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

выполнялась раза в 3 дольше.
Очень странно. Стандарт SQL не регламентирует порядок выдачи записей при отсутствии order by.
Поэтому, MySQL по уму должен выдать первую попавшуюся запись из таблицы, на что всяко 9 секунд не надо.
Даже самый дурацкий замысел можно воплотить мастерски
UUU
Сообщения: 310
Зарегистрирован: 17 фев 2004, 09:27
Откуда: Иваново
Контактная информация:

9 секунд - это на 10000 цапросов, т.е. 0.0009 секунды на запрос.
Поставил order by по дате и создал индекс по ней - запрос стал выполняться за 10-6 секунд.
Аватара пользователя
AiK
Сообщения: 2287
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

UUU, я имел ввиду не абсолютные показатели, а относительные.
запрос

Код: Выделить всё

select q,w,e,r,t,y,u,i from my_table where 1 limit 1
по определению должен выполняться быстрее, чем

Код: Выделить всё

select q,w,e,r,t,y,u,i from my_table where 1 
Поставил order by
Это почти всегда замедляет запрос. Т.к. данные сначала выбираются в промежуточную таблицу для сортировки, а уже потом тебе приходит выдача из этой таблицы.
Чтобы ускорить этот процесс придуманы кластеризованные индексы - данные в таблице физически располагаются в нужном порядке, таким образом при совпадении направления order by необходимость в построении промежуточного результата отпадает. Кластеризованный индекс по определению может быть только один на таблицу. Разумеется может быть составным.
Не знаю, есть ли такие индексы в MySQL, мануал искать лень.
Даже самый дурацкий замысел можно воплотить мастерски
Ответить