трабла с индексами

Kirill

Новичок
трабла с индексами

Есть запрос:
Код:
SELECT 
price.id, price.price_from, price.price_under 
FROM 
pref_announcement_price price 
INNER JOIN pref_announcement_price_cat price_cat ON price_cat.id=price.id_parent 
INNER JOIN pref_announcement a ON a.id=price_cat.id_announcement 
INNER JOIN pref_announcement_cities c ON c.id_announcement=a.id 
INNER JOIN pref_users u ON u.id=a.id_user 
INNER JOIN pref_partners p ON p.id=u.id_partner 
WHERE 
lower(price.name)=lower('siemens C55') 
AND price.visible=1 
AND price_cat.visible=1 
AND a.visible=1 
AND a.is_active=1 
AND a.sms_balance>0 
AND a.is_modering=1 
AND c.id_city IN (3) 
AND u.visible=1 
AND u.user_active=1 
AND p.visible=1;
результат explaina данного запроса:
+----+-------------+-----------+--------+-----------------+-----------------+---------+--------------------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+--------+-----------------+-----------------+---------+--------------------------------------+------+-------------+
| 1 | SIMPLE | price | ALL | id_parent_2 | NULL | NULL | NULL | 31 | Using where |
| 1 | SIMPLE | price_cat | eq_ref | PRIMARY | PRIMARY | 4 | mir_portal.price.id_parent | 1 | Using where |
| 1 | SIMPLE | a | eq_ref | PRIMARY | PRIMARY | 2 | mir_portal.price_cat.id_announcement | 1 | Using where |
| 1 | SIMPLE | u | eq_ref | PRIMARY | PRIMARY | 4 | mir_portal.a.id_user | 1 | Using where |
| 1 | SIMPLE | p | eq_ref | PRIMARY | PRIMARY | 4 | mir_portal.u.id_partner | 1 | Using where |
| 1 | SIMPLE | c | ref | id_announcement | id_announcement | 4 | mir_portal.a.id | 1 | Using where |
+----+-------------+-----------+--------+-----------------+-----------------+---------+--------------------------------------+------+-------------+

почему тип соединения у таблицы price ALL? какие индексы нужно создать чтобы был другой тип соединения, или тут не в индексах дело(записей в таблице около 70, путем объединений остается 31, мускул думает что быстрее будет просканировать эти 30 строчек, а не использовать индексы)?
Создавал индекс на полях:
id_parent
name
visible
На поле id_parent
на полях
id_parent
name
все-равно один и тот же результат
Структура таблицы price:
+-------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------+------+-----+---------+----------------+
| id | int(11) | | PRI | NULL | auto_increment |
| id_parent | int(11) | | MUL | 0 | |
| name | char(50) | | MUL | | |
| description | char(255) | | | | |
| price_from | float | | | 0 | |
| price_under | float | | | 0 | |
| visible | tinyint(1) | | | 1 | |
+-------------+------------+------+-----+---------+----------------+
или я что-то не так делаю?
 

Wicked

Новичок
где-то я такое уже видел ;)

не используй "lower(price.name)=lower('siemens C55')", т.к. это запрещает использовать индексы по name. Причем я почти уверен, что ничего не изменится.
 

Kirill

Новичок
где-то я такое уже видел
если ты о том, что это откуда-то стырино/дорабатывается готовый движок - ошибаешься, все самописное
попробую не использовать lower.

-~{}~ 25.07.06 14:55:

правильно ли я создаю индекс для данной ситуации:
в индексе поле id_parent должно идти первым, за ним поле name, потом visible? или создать индекс только на name и visible?
 

Wicked

Новичок
в следующий раз, вместо того, чтобы на пальцах описывать, какие у тебя есть индексы и поля, пости лучше рез-т запроса SHOW CREATE TABLE `table`.

Но, насколько я понял, индексы у тебя все же сделаны неправильно. В составных индексах используются только leftmost prefix'ы. Дак вот. Mysql наверное не видит смысла использовать p.id_parent совсем. А оставшиеся 2 поля из этого индекса оно уже использовать не может.
 

Kirill

Новичок
ок, спасибо, значит нужен индекс по name и visible, а id_parent оставить без индекса, так?
 

zerkms

TDD infected
Команда форума
Kirill
чтобы узнать какие индексы нужно создавать, и при этом ты не в состоянии проделать анализ для такого большого запроса - пиши его итеративно, постепенно добавляя условия в WHERE и объединения, попутно смотря в explain
и не забудь таблу забить данными (чтобы не превысить порог ~30%)
 

Kirill

Новичок
mysql зачастую и так делает case insensitive сравнения, так что lower, скорее всего, лишний.
а как это конкретно проверить? Среди переменных нашел только lower_case_table_names и lower_case_file_system что немного не то.
 
Сверху