Мускул не использует составной индекс

Falc

Новичок
Мускул не использует составной индекс

Ситуация следующая:

есть 2 таблицы: a и b

Из них делается следующая выборка:
[sql]
SELECT *
FROM a
INNER JOIN b ON b.a_id = a.id AND b.x < 12
WHERE a.y = 24
[/sql]
В таблице b есть составной ключ по полям a_id,x
Так вот в таком запросе используеться только первая часть ключа.

В тоже время запрос
[sql]
SELECT *
FROM b
WHERE b.a_id = 18 AND b.x < 12
[/sql]
Использует полный составной ключ.

Кто-нибудь встречался с такой проблемой?
Можно ли заставить использовать Мускул полный составной ключ?
 

Demiurg

Guest
Все правильно, на ч у тебя индекса нет.
 

Demiurg

Guest
потому что составной индех - это не индекс по каждому полю.
 

Falc

Новичок
Originally posted by Demiurg
потому что составной индех - это не индекс по каждому полю.
Это что урок ликбеза?
Я спрашиваю по чему не используется индекс в первом случае,
хотя в практически индентичной выборке он используется?
 

tony2001

TeaM PHPClub
[sql]
EXPLAIN SELECT *
FROM a
INNER JOIN b ON b.a_id = a.id AND b.x < 12
WHERE a.y = 24
[/sql]
так что говорит?

[sql]
SELECT *
FROM a
INNER JOIN b ON b.a_id = a.id AND b.x < 12 USE INDEX (sostavnoy_index)
WHERE a.y = 24
[/sql]
а так?
 

Falc

Новичок
Originally posted by tony2001
[sql]
EXPLAIN SELECT *
FROM a
INNER JOIN b ON b.a_id = a.id AND b.x < 12
WHERE a.y = 24
[/sql]
так что говорит?

[sql]
SELECT *
FROM a
INNER JOIN b ON b.a_id = a.id AND b.x < 12 USE INDEX (sostavnoy_index)
WHERE a.y = 24
[/sql]
а так?
Он индекс использует но не полностью а только первую его часть.
 

Falc

Новичок
Да нету у меня таблиц а и б, я просто привел их для примера.
 

Апельсин

Оранжевое создание
ну какие-то же таблицы у тебя есть?
вот для тех которые есть и покажи.
 

Falc

Новичок
Originally posted by Апельсин
ну какие-то же таблицы у тебя есть?
вот для тех которые есть и покажи.
Вот эксплаин для первого моего запроса:
[sql]
EXPLAIN SELECT *
FROM bs_link
INNER JOIN bs_session ON bs_link.id = bs_session.link_id AND bs_session.depth < 3
WHERE bs_link.password_id = 5
[/sql]
bs_link ref PRIMARY,password_id password_id 2 const 107 Using where
bs_session ref link_id link_id 3 bs_link.id 3 Using where


А вот для второго:
[sql]
EXPLAIN SELECT *
FROM bs_session
WHERE bs_session.link_id = 1 AND bs_session.depth < 3
[/sql]
bs_session range link_id link_id 4 NULL 1398 Using where
 

tony2001

TeaM PHPClub
сделай:
show create table bs_link;
show create table bs_session;

результат кинь сюда.
все ненужные поля можно убрать.
я посмотрю.
 

Falc

Новичок
[sql]
CREATE TABLE `bs_link` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`refer_id` mediumint(8) unsigned NOT NULL default '0',
`location_id` smallint(5) unsigned NOT NULL default '0',
`search_id` mediumint(8) unsigned NOT NULL default '0',
`password_id` smallint(5) unsigned NOT NULL default '0',
`host_id` smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `password_id` (`password_id`),
KEY `location_id` (`location_id`),
KEY `refer_id` (`refer_id`)
)
[/sql]
[sql]
CREATE TABLE `bs_session` (
`id` int(10) unsigned NOT NULL auto_increment,
`visitor_id` mediumint(8) unsigned NOT NULL default '0',
`link_id` mediumint(8) unsigned NOT NULL default '0',
`path_id` mediumint(8) unsigned NOT NULL default '0',
`depth` tinyint(3) unsigned NOT NULL default '0',
`finish` timestamp(14) NOT NULL,
`start` timestamp(14) NOT NULL,
PRIMARY KEY (`id`),
KEY `visitor_id` (`visitor_id`),
KEY `link_id` (`link_id`,`depth`)
)
[/sql]
 

tony2001

TeaM PHPClub
Код:
mysql> EXPLAIN SELECT *
    -> FROM bs_link
    -> INNER JOIN bs_session ON bs_link.id = bs_session.link_id AND bs_session.depth < 3
    -> WHERE bs_link.password_id = 5;
+----+-------------+------------+--------+---------------------+---------+---------+------+------+-------------+
| id | select_type | table      | type   | possible_keys       | key     | key_len | ref  | rows | Extra       |
+----+-------------+------------+--------+---------------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | bs_link    | system | PRIMARY,password_id | NULL    |    NULL | NULL |    1 |             |
|  1 | SIMPLE      | bs_session | range  | link_id             | link_id |       4 | NULL |    2 | Using where |
+----+-------------+------------+--------+---------------------+---------+---------+------+------+-------------+
Код:
mysql> EXPLAIN SELECT *
    -> FROM bs_session
    -> WHERE bs_session.link_id = 1 AND bs_session.depth < 3;
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table      | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | bs_session | range | link_id       | link_id |       4 | NULL |    1 | Using where |
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
еще раз объясни, плз, что тебя смущает тут.
 

Апельсин

Оранжевое создание
Тони, у него немного другой вывод EXPLAIN.
У тебя как раз все в порядке.
 

Falc

Новичок
Действительно страно, но у тони все работает.
Тони у тебя какой Мускул?
У меня 4.0.15
 

Апельсин

Оранжевое создание
Falc - поведение оптимизатора очень сильно зависит от данных, потому ничего странного в общем-то нет.

выполни ANALYZE, посмотри измениться ли что-нибудь.
 
Сверху