2016-02-10 3 views
0

Когда я сделать простой запрос, как, например, следующие:MariaDB запроса (соединение) не используется индекс

SELECT `visits`.`item_id`, `visits`.`hits` FROM `visits` ORDER BY `visits`.`hits` DESC LIMIT 10; 

Ну, это работает, и позвольте мне получить верхние десять строк в таблице visits. Однако, когда я присоединиться к столу для получения информации, мне нужно, это занимает гораздо больше времени (> 1 сек), вот как я это сделать:

SELECT `visits`.`item_id`, `visits`.`hits`, `item`.`id`, `item`.`title`, `item`.`url` FROM `visits` 
INNER JOIN `item` ON `visits`.`item_id`=`item`.`id` 
ORDER BY `visits`.`hits` DESC 
LIMIT 10; 

Ну, это делает работу, но занимает больше секунды чтобы придумать результаты. Я побежал запрос с объяснения, и он говорит:

id: simple 
select_type: simple 
table item 
type ALL 
possible_keys PRIMARY 
key NULL 
key_len NULL 
ref NULL 
Rows 4735 
Extra Using temporary, using filesort 

id: simple 
select_type: simple 
table visits 
type ref 
possible_keys visits_item_id 
key visits_item_id 
key_len 4 
ref item.item_id 
Rows 8 
Extra 

Я не эксперт здесь, но он смотрит на меня, как запрос не использует индекс на item. item_id, чтобы найти item. И я не знаю, как сделать этот запрос быстрее. Есть идеи? любая помощь будет так оценена, спасибо!

CREATE TABLE заявления для обеих таблиц:

CREATE TABLE `visits`(
`id` int(11) NOT NULL AUTO_INCREMENT, 
`item_id` int(11) NOT NULL, 
`hits` int(11) NOT NULL, 
KEY `visits_item_id` (`item_id`) 
KEY `hits` (`hits`) 
CONSTRAINT `visits_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `item` (`id`)) ENGINE=InnoDB AUTO_INCREMENT=99427 DEFAULT CHARSET=utf8 

CREATE TABLE `item` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`title` varchar(255) NOT NULL, 
`url` varchar(255) NOT NULL 
PRIMARY Key(`id`)) ENGINE=InnoDB AUTO_INCREMENT=6287 DEFAULT CHARSET=utf8 

Больше информации Я создал эти таблицы с помощью peewee. После того, как я создал таблицы с Peewee, я создал индекс на visits. hits.

** Показать профиль: запустив SET PROFILING=1; **

+----------------------+----------+ 
| Status    | Duration | 
+----------------------+----------+ 
| starting    | 0.000106 | 
| checking permissions | 0.000008 | 
| checking permissions | 0.000003 | 
| checking permissions | 0.000002 | 
| checking permissions | 0.000004 | 
| Opening tables  | 0.000028 | 
| After opening tables | 0.000007 | 
| System lock   | 0.000006 | 
| Table lock   | 0.000004 | 
| After opening tables | 0.000006 | 
| init     | 0.000037 | 
| optimizing   | 0.000033 | 
| statistics   | 0.000075 | 
| preparing   | 0.000049 | 
| executing   | 0.000005 | 
| Copying to tmp table | 0.000510 | 
| Copying to tmp table | 0.813779 | 
| Sorting result  | 0.027571 | 
| Sending data   | 0.000040 | 
| end     | 0.000004 | 
| removing tmp table | 0.000298 | 
| end     | 0.000005 | 
| query end   | 0.000005 | 
| closing tables  | 0.000013 | 
| freeing items  | 0.000007 | 
| updating status  | 0.000020 | 
| cleaning up   | 0.000005 | 
+----------------------+----------+ 
+0

Показать инструкции 'CREATE TABLE' для обеих таблиц. Я думаю, что 'item.item_id' является ключом PRIMARY, и если да, то он используется:' possible_keys PRIMARY' – hjpotter92

+0

Ваше предложение join использует индекс, но похоже, что предложение order by создает проблему, вам нужно добавить index для 'visit.hits' и увидеть разницу. –

+0

@ hjpotter92 Я обновил свой вопрос с информацией и поблагодарил вас за интерес – gglasses

ответ

0

Каждый InnoDB таблица должна иметь PRIMARY KEY, предпочтительно явно. У вас есть AUTO_INCREMENTs - сделайте их PRIMARY KEY, тоже.

Вам нужны оба из них в списке SELECT; они одинаковы? .. visits. item_id, item. id