Оптимизация запроса

Solid

Drosera anglica
Оптимизация запроса

Запрос работает великолепно, только в 10 раз медленнее, чем надо. Пожалуйста, знающие люди, помогите, чем можете...

Код:
SELECT 
SQL_CACHE 
SQL_CALC_FOUND_ROWS 
artist.*, 
COUNT(DISTINCT album.album_id) AS artist_album_count, 
COUNT(DISTINCT song.song_id) AS artist_song_count, 
COUNT(DISTINCT lyric.lyric_id) AS artist_lyric_count, 
ROUND(SUM(song2rate.rate_count)/COUNT(song2rate.song_id)) AS artist_rate, 
COUNT(DISTINCT comment.comment_id) AS artist_comment_count 
FROM 
artist 
LEFT JOIN album ON artist.artist_id=album.artist_id 
LEFT JOIN song ON album.album_id=song.album_id 
LEFT JOIN lyric ON lyric.song_id=song.song_id 
LEFT JOIN song2rate ON song2rate.song_id=song.song_id 
LEFT JOIN comment ON comment.song_id=song.song_id 
WHERE 
artist.artist_name REGEXP '^a.*$' GROUP BY artist.artist_id 
ORDER BY artist.artist_name ASC
Все поля проиндексированны (используются все виды индексов unique, primary, index).
Используется mysql 4.1.
 

Solid

Drosera anglica
REGEXP работает достаточно быстро, проблема не в нём. :)
 

Wicked

Новичок
Solid, не надо тут сказки рассказывать. Regexp никогда не использует индексы. А like в этом случае долен бы.

2) зачем там SQL_CALC_FOUND_ROWS ?

3) я бы попробовал сделать составные индексы (song.album_id, song.song_id), (album.artist_id, album.album_id)

4) покажи, что говорит explain.
 

Solid

Drosera anglica
1) REGEXP работает немного медленнее LIKE, но всё же не так критично, как всё остальное. Падение производительности где-то всего лишь в двое.
2) Думаете просто так? Естественно в следующем запросе использую FOUND_ROWS().
3) Насколько составные индексы лучше обычных?
4)
Код:
id  	 select_type  	 table  	 type  	 possible_keys  	 key  	 key_len  	 ref  	 rows  	 Extra
1 	SIMPLE 	artist 	ALL 	NULL 	NULL 	NULL 	NULL 	4416 	Using where; Using temporary; Using filesort
1 	SIMPLE 	album 	ref 	artist_id 	artist_id 	4 	song2play.artist.artist_id 	12 	 
1 	SIMPLE 	song 	ref 	album_id 	album_id 	4 	song2play.album.album_id 	13 	 
1 	SIMPLE 	lyric 	ref 	song_id 	song_id 	4 	song2play.song.song_id 	12 	 
1 	SIMPLE 	song2rate 	ref 	song_id 	song_id 	4 	song2play.song.song_id 	12 	 
1 	SIMPLE 	comment 	ref 	song_id 	song_id 	4 	song2play.song.song_id 	15
 

Wicked

Новичок
1) т.е. тебя приходится уговаривать внять советам, которые тебе дают прирост производительности ВДВОЕ? на остальное отвечать даже не буду.
 

Solid

Drosera anglica
Да мне нужен REGEXP. Не хотите - не отвечайте, мне то что!? Я уверен, что вы и ничего дельного то посоветовать не можете.

-~{}~ 22.04.06 20:06:

Думаете я бы использовал REGEXP, если бы у меня была бы конструкция типа ^[a].*$? К примеру мне нужно использовать ^[0-9].*$, через LIKE это уже сделать невозможно. Да и суть то не в этом. Что REGEXP, что LIKE.. да что я в самом деле тут пытаюсь сказать, не хотите - не надо... всёравно не знаете, ибо, если бы знали - сказали бы.
 

Wicked

Новичок
ок.

1) зато с этим замечательно справится оператор =
where artist_name_first_letter in ('a')
where artist_name_first_letter in ('0', '1', '2', ...)

2)
Естественно в следующем запросе использую FOUND_ROWS().
Ну дак и используй. SQL_CALC_FOUND_ROWS то тут причем? (намкаю на то, что либо SQL_CALC_FOUND_ROWS вообще не нужен, либо приведенный пример не соответствует реальному запросу)

3)
Indexes are used for these operations:
...
* In some cases, a query can be optimized to retrieve values without consulting the data rows. If a query uses only columns from a table that are numeric and that form a leftmost prefix for some key, the selected values may be retrieved from the index tree for greater speed:
SELECT key_part3 FROM tbl_name WHERE key_part1=1
 

svetasmirnova

маленький монстрик
>да что я в самом деле тут пытаюсь сказать
И в самом деле.
 

fisher

накатила суть
GROUP BY artist.artist_id
ORDER BY artist.artist_name

похоже даёт

Using temporary; Using filesort

попробуй убрать сортировку и померь, даст пищу для

а вообще тебе похоже нужно сильно денормализовывать чтобы не было динамического вычисления всех counters, и на artist.artist_name придется либо полный либо частичный индекс (первые несколько символов) - в зависимости от жесткости требований
 

Solid

Drosera anglica
fisher
Мне тоже кажется, что единственное решение всего этого безобразия возможно только через статику, т.е. высчитывать не в процессе выполнения запроса...
Что ж, Всем спасибо за участие.
 
Сверху