Страница 1 из 1

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

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

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

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 
Как бы его с оптимизировать, и какие индексы для этого лучше создать.
Буду премного благодарен.

Добавлено: 17 янв 2005, 18:10
AiK
Индексы просятся на status и Number.
Условие для DateTime_web выглядит подозрительным.
and direction.Number=SUBSTRING_INDEX(s_in.daddr,'\ ',1)
Тоже не быстрая конструкция. Всегда предпочтительнее все Join'ы делать по связкам PK-FK.

Добавлено: 18 янв 2005, 08:15
UUU
Спасибо.
Нашел одно лишнее условие

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

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

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

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

выполнялась раза в 3 дольше.

Добавлено: 18 янв 2005, 17:35
AiK
выполнялась раза в 3 дольше.
Очень странно. Стандарт SQL не регламентирует порядок выдачи записей при отсутствии order by.
Поэтому, MySQL по уму должен выдать первую попавшуюся запись из таблицы, на что всяко 9 секунд не надо.

Добавлено: 19 янв 2005, 07:57
UUU
9 секунд - это на 10000 цапросов, т.е. 0.0009 секунды на запрос.
Поставил order by по дате и создал индекс по ней - запрос стал выполняться за 10-6 секунд.

Добавлено: 19 янв 2005, 13:48
AiK
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, мануал искать лень.