SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 13.06.2011 21:52:57

lexey2006.90
Участник
Зарегистрирован: 01.06.2011
Сообщений: 16

Оптимизиция запроса select ... where ... order by price limit 200 из бд в 18 000 000 записей

База:
CREATE TABLE IF NOT EXISTS `gate_spo_price_egipt_table` (
  `id` bigint(16) NOT NULL AUTO_INCREMENT,
  `date_from` date NOT NULL,
  `date_to` date NOT NULL,
  `country` int(11) NOT NULL,
  `city` int(11) NOT NULL,
  `hotel` int(11) NOT NULL,
  `operator` int(11) NOT NULL,
  `star` int(11) NOT NULL,
  `room` int(11) NOT NULL,
  `pansion` int(11) NOT NULL,
  `depature_from` int(11) NOT NULL,
  `depature_to` int(11) NOT NULL,
  `depature_date` date NOT NULL,
  `days` int(11) NOT NULL,
  `price` int(11) NOT NULL,
  `status` tinyint(4) NOT NULL,
  `chld` int(11) NOT NULL,
  `age1` int(11) NOT NULL,
  `age2` int(11) NOT NULL,
  `age3` int(11) NOT NULL,
  `age4` int(11) NOT NULL,
  PRIMARY KEY (`id`,`depature_date`),
  KEY `seach_gate` (`depature_date`,`room`,`days`,`status`,`operator`,`chld`,`hotel`),
  KEY `seach_sort` (`price`,`depature_date`,`room`,`days`,`status`,`operator`,`chld`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
/*!50100 PARTITION BY RANGE (DAYOFYEAR(depature_date))
(PARTITION p0 VALUES LESS THAN (152) ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (158) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (164) ENGINE = InnoDB,
PARTITION p3 VALUES LESS THAN (170) ENGINE = InnoDB,
PARTITION p4 VALUES LESS THAN (176) ENGINE = InnoDB,
PARTITION p5 VALUES LESS THAN (181) ENGINE = InnoDB,
PARTITION p6 VALUES LESS THAN (187) ENGINE = InnoDB,
PARTITION p7 VALUES LESS THAN (194) ENGINE = InnoDB,
PARTITION p8 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */ AUTO_INCREMENT=40039238726 ;

Неактивен

 

#2 13.06.2011 21:56:26

lexey2006.90
Участник
Зарегистрирован: 01.06.2011
Сообщений: 16

Re: Оптимизиция запроса select ... where ... order by price limit 200 из бд в 18 000 000 записей

запрос вида : select * from gate_spo_price_egipt_table use index (seach_key) where depature_date >= 2011-06-20 and depature_date <= 2011-06-30 and room = 23 order by price asc limit 200.
Выполняется 4 минуты, что неприемлимо. Конфигурацию сервера и субд менять слишком дорого.
Применяется:
1. Индекс
2. Партицирование по 6 дней (для быстрого поиска)

Неактивен

 

#3 13.06.2011 21:58:30

lexey2006.90
Участник
Зарегистрирован: 01.06.2011
Сообщений: 16

Re: Оптимизиция запроса select ... where ... order by price limit 200 из бд в 18 000 000 записей

Вопрос 1. Как правильно расставляются комбинированные индексы (по неск. полям сразу), потому, что они были до начала оптимизации?
Вопрос 2. Какие еще варианты оптимизации можно применить?

Неактивен

 

#4 14.06.2011 12:31:31

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: Оптимизиция запроса select ... where ... order by price limit 200 из бд в 18 000 000 записей

Для начала давайте посмотрим EXPLAIN

Неактивен

 

#5 14.06.2011 15:22:26

lexey2006.90
Участник
Зарегистрирован: 01.06.2011
Сообщений: 16

Re: Оптимизиция запроса select ... where ... order by price limit 200 из бд в 18 000 000 записей

Давайте. EXPLAIN чего именно? запроса или базы? Можете рассказать как мне с помощью EXPLAIN отследить какая часть запроса тормозит?

Неактивен

 

#6 14.06.2011 16:35:19

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: Оптимизиция запроса select ... where ... order by price limit 200 из бд в 18 000 000 записей

lexey2006.90 написал:

Давайте. EXPLAIN чего именно? запроса или базы? Можете рассказать как мне с помощью EXPLAIN отследить какая часть запроса тормозит?

EXPLAIN select * from gate_spo_price_egipt_table use index (seach_key) where depature_date >= 2011-06-20 and depature_date <= 2011-06-30 and room = 23 order by price asc limit 200;

Неактивен

 

#7 14.06.2011 18:12:28

lexey2006.90
Участник
Зарегистрирован: 01.06.2011
Сообщений: 16

Re: Оптимизиция запроса select ... where ... order by price limit 200 из бд в 18 000 000 записей

mysql> explain select * from gate_spo_price_egipt use index (seach_sort) where depature_date >= 2011-06-20 and depature_date <= 2011-06-30 and room = 23 order by price asc limit 200;
+----+-------------+----------------------+------+---------------+------+---------+------+------+-----------------------------+
| id | select_type | table                | type | possible_keys | key  | key_len | ref  | rows | Extra                       |
+----+-------------+----------------------+------+---------------+------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | gate_spo_price_egipt | ALL  | NULL          | NULL | NULL    | NULL |    0 | Using where; Using filesort |
+----+-------------+----------------------+------+---------------+------+---------+------+------+-----------------------------+
1 row in set, 4 warnings (0.00 sec)

Неактивен

 

#8 14.06.2011 23:41:18

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: Оптимизиция запроса select ... where ... order by price limit 200 из бд в 18 000 000 записей

 KEY `seach_gate` (`depature_date`,`room`,`days`,`status`,`operator`,`chld`,`hotel`),
  KEY `seach_sort` (`price`,`depature_date`,`room`,`days`,`status`,`operator`,`chld`)


А зачем вообще эти комбинации ? Они используются в других запросах ?

select * from gate_spo_price_egipt use index (seach_sort) where depature_date >= 2011-06-20 and depature_date <= 2011-06-30 and room = 23 order by price asc limit 200

Для вашего запроса нужен индекс
KEY `seach_sort` (`depature_date`,`room`,`price`)


Сделайте EXPLAIN на запрос который возвращает какие то данные.

Как сделайте новую комбинацию индексов можно попробовать и без use index.

Не обязательно создавать индекс сразу на наполненную таблицу, создайте копию её структуры, залейте туда пару тысяч записей, и потестите.

Неактивен

 

#9 15.06.2011 18:18:50

lexey2006.90
Участник
Зарегистрирован: 01.06.2011
Сообщений: 16

Re: Оптимизиция запроса select ... where ... order by price limit 200 из бд в 18 000 000 записей

Как сделать так, чтобы запрос с explain возвращал значения, потому, что запрос:
select * from gate_spo_price_egipt use index (seach_sort) where depature_date >= 2011-06-20 and depature_date <= 2011-06-30 and room = 23 order by price asc limit 200 - возвращает значения, но в то же время запрос:
explain select * from gate_spo_price_egipt use index (seach_sort) where depature_date >= 2011-06-20 and depature_date <= 2011-06-30 and room = 23 order by price asc limit 200 возвращает то, что написал в прошлом письме.

По поводу индексов: у меня возможен поиск по полям (указывается в форме):
`country` (уже разделил таблицу по странам - можно не указывать. на форме можно выбрать только 1 страну, так что соединение таблиц не происходит)
`city`
`hotel`
`operator`
`star`
`room`
`days`
`price` - поэтому и в индексе содержится почти все.
По `depature_date` (по 6 дней сделал партицирование).

По поводу тестирования: mysql кэширует запросы (даже похожие). Поэтому невозможно понять сколько будет выполняться запрос. Можно ли отключить кэширование? На серваке стоит mysql 5.5.13.

Неактивен

 

#10 15.06.2011 18:21:29

lexey2006.90
Участник
Зарегистрирован: 01.06.2011
Сообщений: 16

Re: Оптимизиция запроса select ... where ... order by price limit 200 из бд в 18 000 000 записей

Еще 1 дополнение: тестирую через консоль на серваке, поэтому других причин тормоза выборки и сортировки быть не может, кроме как объем таблицы.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson