Помогите оптимизировать запрос.

zdimon

Новичок
Помогите оптимизировать запрос.

select count(id) as count from content use index(date_expire) where id_category=41 and date_expire>NOW() and pub=1

Хостер говорит что он выполняется до 50 сек.

По полям date_expire, id_category и pub индексы проставлены.

В таблице 4153 записи.
Размер таблицы 172.2 мб.
 

baev

‹°°¬•
Команда форума
Где результат EXPLAIN'а?

(Вообще, мне кажется, что будет достаточно заменить NOW() на реальное число.)
 

Gas

может по одной?
будет достаточно заменить NOW() на реальное число
по идее, в таком запросе mysql сам заменяет на константу перед выполнением.
Тормозит скорее из-за обращений к файлу с данными.

zdimon
Решение в лоб, сосьавной индекс (id_category,pub,date_expire) и замена count(id) на count(*) если в id не могут быть NULL

-~{}~ 18.04.08 12:13:

Вопрос к знатокам. В данном примере, когда созданы 3 отдельных индекса, mysql выбирает лучший _одни_ из них (myisam таблица и не учитываем index merge), а источником данных для других индексных полей будет data-файл или индексный ? Всегда хотел узнать, да как-то руки не доходили.
 

zdimon

Новичок
Автор оригинала: baev
Где результат EXPLAIN'а?

(Вообще, мне кажется, что будет достаточно заменить NOW() на реальное число.)
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE content range date_expire date_expire 4 NULL 1472 Using where
 

zerkms

TDD infected
Команда форума
В таблице 4153 записи.
фулскан 4к записей займёт 0.1с максимум, и то я даже не уверен что будет так много

для других индексных полей будет data-файл или индексный
если он не использует индекс - как он из него будет брать данные? :)
 

Gas

может по одной?
как он из него будет брать данные? :)
тоже верно :)
вернее имел ввиду не сам индексный файл, а key_buffer - думал может он организован более хитро чем просто b-tree.

фулскан 4к записей займёт 0.1с максимум
размер таблицы 170 MB и если доступ идёт к данным, то может быть совсем не 0.1 с
 

zdimon

Новичок
Автор оригинала: alpine
zdimon
Покажи SHOW CREATE TABLE content
CREATE TABLE `content` (
`id` int(11) NOT NULL auto_increment,
`title` text,
`introtext` text,
`alltext` text,
`id_category` int(11) default NULL,
`id_razdel` int(11) default NULL,
`meta_desc` text,
`meta_key` text,
`created` datetime default NULL,
`modified` datetime default '0000-00-00 00:00:00',
`image` varchar(250) default '0',
`ordering` int(11) default NULL,
`access` int(3) default NULL,
`hits` int(11) default '0',
`pub` int(1) default '1',
`onmain` int(1) default '0',
`id_producer` int(11) default NULL,
`fl_coment` int(1) default '1',
`date_expire` date default NULL,
`fl_mon` int(1) default '0',
`fl_nal` int(1) default '0',
`fl_hoz` int(1) default '0',
`created_by` int(11) default NULL,
`modified_by` int(11) default NULL,
PRIMARY KEY (`id`),
KEY `id_category` (`id_category`),
KEY `id_razdel` (`id_razdel`),
KEY `id_producer` (`id_producer`),
KEY `ordering` (`ordering`),
KEY `pub` (`pub`),
KEY `title` (`title`(10)),
KEY `introtext` (`introtext`(10)),
KEY `alltext` (`alltext`(10)),
KEY `onmain` (`onmain`),
KEY `date_expire` (`date_expire`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
 

Magz

Новичок
Я бы сделал составной индекс на три поля, по которым идет поиск, причем, порядок полей в индексе должен соответствовать порядку полей в поисковом запросе.
Для колонки date_expire поставил бы NOT NULL.
Если в поле pub содержатся значения только 0 и 1, то я бы делал поиск pub > 0 - если я не ошибаюсь, такой поиск будет работать быстрее, т.к. сравнение идет только с нулем и не вычисялется конкретное значение поля.
 
Сверху