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

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 индексированы

куда копать?
 

Gas

может по одной?
попробуй
Код:
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
 

fStrange

Новичок
Gas
попробовал, получилось тяжелее 0,227 и больше строк обходит
видимо придется менять структуру таблиц
 

Gas

может по одной?
Странно что медленнее получилось (в mysql'е), explain приведёшь?
1. если для теста выполнить запрос, в котором вместо IN (select ...) будут стоять уже константные значения - результаты подзапроса, будет ощутимо быстрее или нет?
2. сколько всего записей возвращается без лимита?
 

fStrange

Новичок
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 строк это вся тестовая таблица, запрос обходит все
 

Gas

может по одной?
10 000 строк это вся тестовая таблица, запрос обходит все
запрос с условием по функции от поля (find_in_set) и должен обойти всю таблицу fa_dirs (правда смысл этого запроса для меня загадка), в твоём первом запросе точно так-же происходит, просто explain не показывает.
 

Wicked

Новичок
думаю, все же было бы лучше просто джоинить fa_dirs (без подзапроса) и сделать ей индекс на dirid, как минимум
 

Gas

может по одной?
Wicked
интересно было б посмотреть на результат этих манипуляций, но мне кажется что картина особо не изменится.
 

fStrange

Новичок
запрос с условием по функции от поля (find_in_set) и должен обойти всю таблицу fa_dirs (правда смысл этого запроса для меня загадка),
директории
pdirs - список родителей разделенный запятой
FIND_IN_SET( '7',pdirs) - список директорий с родителем "7"

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

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