оптимизировать запрос

fStrange

Новичок
оптимизировать запрос

PHP:
$sQuery = "SELECT SQL_CALC_FOUND_ROWS id, fname, rate
FROM fa_files, fa_info
WHERE fa_files.dirid
IN (

SELECT dirid
FROM fa_dirs
WHERE FIND_IN_SET( '7', CONCAT( ',', pdirs ) )
)
AND fa_files.id = fa_info.fid
ORDER BY fa_info.rate DESC
LIMIT 0 , 20";

запрос тяжеловат и исполняется 0,217 сек на тестовой базе

Код:
id 	select_type 	table 	type 	possible_keys 	key 	key_len 	ref 	rows 	Extra
1 	PRIMARY 	fa_info 	ALL 	PRIMARY 	NULL 	NULL 	NULL 	10000 	Using filesort
1 	PRIMARY 	fa_files 	eq_ref 	PRIMARY 	PRIMARY 	3 	fa_info.fid 	1 	Using where
2 	DEPENDENT SUBQUERY 	fa_dirs 	unique_subquery 	PRIMARY 	PRIMARY 	3 	func 	1 	Using index; Using where

поля rate, id, fid, pdirs которые используются в WHERE индексированы

куда копать?
 
попробуй
Код:
SELECT SQL_CALC_FOUND_ROWS id, fname, rate 
FROM 
  (SELECT dirid 
   FROM fa_dirs 
   WHERE FIND_IN_SET( '7', CONCAT( ',', pdirs ) ) ) AS t
JOIN fa_files ON fa_files.dirid = t.dirid
JOIN fa_info ON fa_info.fid = fa_files.id
ORDER BY fa_info.rate DESC 
LIMIT 0 , 20
 
Gas
попробовал, получилось тяжелее 0,227 и больше строк обходит
видимо придется менять структуру таблиц
 
Странно что медленнее получилось (в mysql'е), explain приведёшь?
1. если для теста выполнить запрос, в котором вместо IN (select ...) будут стоять уже константные значения - результаты подзапроса, будет ощутимо быстрее или нет?
2. сколько всего записей возвращается без лимита?
 
Wicked
а смысл? find_in_set не умеет использовать индексы
я то об этом не знаю, знаний нехватка
пробовал LIKE результат хуже

2 Gas
Код:
id 	select_type 	table 	type 	possible_keys 	key 	key_len 	ref 	rows 	Extra
1 	PRIMARY 	<derived2> 	ALL 	NULL 	NULL 	NULL 	NULL 	122 	Using temporary; Using filesort
1 	PRIMARY 	fa_files 	ref 	PRIMARY,dirid 	dirid 	3 	t.dirid 	909 	 
1 	PRIMARY 	fa_info 	eq_ref 	PRIMARY 	PRIMARY 	3 	fa_files.id 	1 	 
2 	DERIVED 	fa_dirs 	ALL 	NULL 	NULL 	NULL 	NULL 	10012 	Using where

10 000 строк это вся тестовая таблица, запрос обходит все
 
10 000 строк это вся тестовая таблица, запрос обходит все
запрос с условием по функции от поля (find_in_set) и должен обойти всю таблицу fa_dirs (правда смысл этого запроса для меня загадка), в твоём первом запросе точно так-же происходит, просто explain не показывает.
 
думаю, все же было бы лучше просто джоинить fa_dirs (без подзапроса) и сделать ей индекс на dirid, как минимум
 
Wicked
интересно было б посмотреть на результат этих манипуляций, но мне кажется что картина особо не изменится.
 
запрос с условием по функции от поля (find_in_set) и должен обойти всю таблицу fa_dirs (правда смысл этого запроса для меня загадка),
директории
pdirs - список родителей разделенный запятой
FIND_IN_SET( '7',pdirs) - список директорий с родителем "7"

выбираю из этой директории файлы с максимальным рейтингом rate
rate в таблице fa_info, dirid в таблице fa_files

получается достаточно корявый запрос
убрал SQL_CALC_FOUND_ROWS скорость получилась приемлема
но жаль
 
Сверху