Страница 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
Спасибо.
Нашел одно лишнее условие
:-)
Но вчера ставил эксперименты. Делал в цикле разные выборки, которые встречаются в коде, чтобы посмотреть, на что тратится время. Делал 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, мануал искать лень.