SQLinfo.ru - Все о MySQL

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

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

Вы не зашли.

#1 27.01.2011 15:18:31

sbury
Участник
Зарегистрирован: 26.01.2011
Сообщений: 9

помогите с построением INDEX к таблице

Доброго всем дня!
Мне уже помогли здесь разобраться с запросом, большое спасибо. Подскажите как правильно построить INDEX
вот пример запроса:

SELECT * FROM price JOIN tour USING ( tour_id ) JOIN hotel USING ( hotel_id )
  WHERE room_id = '1' AND price.price_data='20110127'
 AND (hotel_country='TR' OR hotel_country='Егип')
 AND price_price >=1 AND price_price <=1500
 AND (hotel_city = "Анкакра" OR hotel_city = "Бангкок");


вот сама таблица price:
CREATE TABLE `price` (
    `id` int(10) NOT NULL auto_increment,
    `tour_id` int(10) NOT NULL default '0',
    `room_id` int(10) NOT NULL default '0',
    `price_data` varchar(25) NOT NULL default '0',
    `price_price` float(10,2) NOT NULL default '0',
    `day` int(4) NOT NULL default '0',
    PRIMARY KEY  (`id`)
) TYPE=MyISAM DEFAULT CHARSET=cp1251;

Правильно ли мыслю:
alter table `price`
add index search ( room_id, price_price, hotel_city));

Извиняюсь, но не посоветовавшись боюсь чего-то сломать.

Вот на всякий случай вывод команды EXPLAIN:
id   select_type     table     type     possible_keys     key     key_len     ref                          rows         Extra
1     SIMPLE     price     ALL             NULL             NULL      NULL      NULL                408929      Using where
1     SIMPLE     tour     eq_ref     PRIMARY     PRIMARY     4     parser.price.tour_id     1     
1     SIMPLE     hotel     eq_ref     PRIMARY     PRIMARY     4     parser.tour.hotel_id     1     Using where

Неактивен

 

#2 28.01.2011 01:50:11

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: помогите с построением INDEX к таблице

Мыслите правильно, нужен действительно индекс, который покроет как
можно большее количество ограничений в WHERE. Есть только «но»:
hotel_city не находится в price, поэтому его добавлять не получится smile

Что касается порядка размещения — лучше в начало индекса ставить
поля, которые наиболее селективные (т.е. выборка одного значения
сужает количество строк б́ольшим образом). Кажется, в данном случае
я бы сделал индекс на (price_data, room_id, price_price). Ну и после
price_price уже ничего больше ставить нельзя, т.к. после диапазонного
поиска индекс уже дальше использоваться не может.

Неактивен

 

#3 29.01.2011 13:01:04

sbury
Участник
Зарегистрирован: 26.01.2011
Сообщений: 9

Re: помогите с построением INDEX к таблице

спасибо.
возник еще один вопрос. в чем разница между записями
KEY `name_key` (.....)
и
INDEX `name_key` (...)

Неактивен

 

#4 29.01.2011 23:39:49

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: помогите с построением INDEX к таблице

Никакой разницы, это полные синонимы.

Неактивен

 

#5 08.02.2011 12:00:18

sbury
Участник
Зарегистрирован: 26.01.2011
Сообщений: 9

Re: помогите с построением INDEX к таблице

ерунда у меня получается с этим индексом sad
У меня получается что в любом запросе даже самом минимальном присутствует в условии WHERE  (hotel_country='TR' OR hotel_country='Егип') AND room_id = '1' AND price.price_data='20110127' ...

то есть, поле 'hotel_country' из таблицы  hotel, а потом уже идут поля из таблицы 'price'. Может необходимо перестроить запрос?
Вот минимальный и он же используемый наиболее часто:

SELECT * FROM price JOIN tour USING ( tour_id ) JOIN hotel USING ( hotel_id )
  WHERE (hotel_country='TR' OR hotel_country='Турция')
 AND room_id = '1' AND price_data>='20110207' AND price_data<='20110219'
 AND price_price >='1' AND price_price <='1500' ORDER BY price_data;


Помогите, не получается.

Отредактированно sbury (08.02.2011 13:22:18)

Неактивен

 

#6 09.02.2011 01:20:48

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: помогите с построением INDEX к таблице

Видимо, нужны индексы на price(price_data), tour(tour_id), hotel(hotel_id).

Неактивен

 

#7 09.02.2011 11:56:54

sbury
Участник
Зарегистрирован: 26.01.2011
Сообщений: 9

Re: помогите с построением INDEX к таблице

Так они есть:

CREATE TABLE `hotel` (
    `hotel_id` int(10) NOT NULL auto_increment,
    `hotel_name` text NOT NULL default '',
    `hotel_country` varchar(255) NOT NULL default '',
    `hotel_city` varchar(255) NOT NULL default '',
    PRIMARY KEY  (`hotel_id`)
) TYPE=MyISAM DEFAULT CHARSET=cp1251;

CREATE TABLE `tour` (
    `tour_id` int(10) NOT NULL auto_increment,
    `tour_name` varchar(255) NOT NULL default '',
    `hotel_id` int(10) NOT NULL default '0',
    PRIMARY KEY  (`tour_id`)
) TYPE=MyISAM DEFAULT CHARSET=cp1251;

на таблицу 'price' построил индекс:  index `search` (room_id,price_data,price_price) и дополнительно создал индекс на 'hotel': index (hotel_country), - больше никаких индексов кроме  PRIMARY нет.
но при таком запросе:

SELECT * FROM price JOIN tour USING ( tour_id ) JOIN hotel USING ( hotel_id )
  WHERE (hotel_country='TR' OR hotel_country='Турция')
 AND room_id = '1' AND price_data>='20110207' AND price_data<='20110219'
 AND price_price >='1' AND price_price <='1500' ORDER BY price_data;

это слабо помогает sad

Может поможет что-то в базе изменить что-бы заработали эти индексы. Не знаю, может в таблицу 'price' создать еще поле hotel_id...


Даже не знаю что я зделал, только заново сделал индекс на hotel_country, и вроде заработало. Вот EXPLAIN:

id     select_type     table     type          possible_keys                      key           key_len     ref                          rows                Extra
1     SIMPLE             price     range     search                                search       31            NULL                          2123             Using where
1     SIMPLE             tour     eq_ref     PRIMARY                             PRIMARY     4            parser.price.tour_id     1     
1     SIMPLE             hotel     eq_ref     PRIMARY,hotel_country         PRIMARY     4            parser.tour.hotel_id     1                Using where

Насколько я понимаю это значит , что работает?

У меня по ходу еще возник вопрос. Индексы будут сами перестраиваться при пополнении базы или время от времени это надо делать самому?

Отредактированно sbury (09.02.2011 13:54:57)

Неактивен

 

#8 09.02.2011 13:59:14

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: помогите с построением INDEX к таблице

А что Вас не устраивает в текущем положении вещей? 500 строк достаете,
вполне нормальная выборка. Дальше, видимо, только денормализацией
действительно.

Индексы будут поддерживаться сами, а вот денормализацию (типа добавления
страны в price) прийдется поддерживать вручную.

Неактивен

 

#9 09.02.2011 15:47:59

sbury
Участник
Зарегистрирован: 26.01.2011
Сообщений: 9

Re: помогите с построением INDEX к таблице

paulus написал:

Индексы будут поддерживаться сами, а вот денормализацию (типа добавления
страны в price) прийдется поддерживать вручную.

А вот это можно по подробней, как это делается?

Неактивен

 

#10 09.02.2011 18:21:54

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: помогите с построением INDEX к таблице

Вручную smile Правда. Т.е. если у Вас вдруг у отеля меняется
страна (например, Египет поделился на пять разных маленьких
подстранок), то в price прийдется обновлять информацию вручную.

Неактивен

 

#11 10.02.2011 12:54:45

sbury
Участник
Зарегистрирован: 26.01.2011
Сообщений: 9

Re: помогите с построением INDEX к таблице

Большое спасибо за популярное объяснение!
возник еще вопрос. если я сбросил базу по mysqldump, индексы сохраняются тоже. Или их необходимо делать заново после восстановления?

Неактивен

 

#12 10.02.2011 23:26:30

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: помогите с построением INDEX к таблице

Эээ... «индексы сами создадутся при восстановлении». Так будет правильнее smile

Неактивен

 

Board footer

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