|
|
|
| Здравствуйте!
имею 2 таблицы:
CREATE TABLE items(
items_id INT(11) NOT NULL AUTO_INCREMENT,
name VARCHAR(255) DEFAULT NULL,
when_added TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
items_manufacturers_id VARCHAR(255) DEFAULT NULL,
items_images_id INT(11) UNSIGNED DEFAULT NULL,
classifier_id INT(11) DEFAULT NULL,
PRIMARY KEY (items_id),
INDEX IX_items_classifier_id (classifier_id)
)
ENGINE = INNODB
AUTO_INCREMENT = 104035
AVG_ROW_LENGTH = 68
CHARACTER SET utf8
COLLATE utf8_general_ci;
|
как видно, индексирована колонка items_id (уникальный ключь)
и вторая таблица:
CREATE TABLE items_prices(
items_prices_id INT(11) NOT NULL AUTO_INCREMENT,
online_stores_items_id INT(11) DEFAULT NULL,
new_price DECIMAL(10, 2) DEFAULT NULL,
available SMALLINT(1) UNSIGNED DEFAULT NULL,
when_added TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
old_price VARCHAR(100) DEFAULT NULL,
description TEXT DEFAULT NULL,
contact_phones TINYTEXT DEFAULT NULL,
currency TINYINT(4) DEFAULT 1
is_current_price BIT(1) DEFAULT b'1',
items_id INT(11) DEFAULT NULL,
PRIMARY KEY (items_prices_id),
INDEX IX_items_prices (items_id)
)
ENGINE = INNODB
AUTO_INCREMENT = 66076
AVG_ROW_LENGTH = 61
CHARACTER SET utf8
COLLATE utf8_general_ci;
|
как видно, индексирована колонка items_id (не уникальный ключь)
в общем вот какая проблема: при простой связки этих таблиц по items_id запрос становится тяжелее и за ежедневного роста не уникальных индексов items_id таблицы items_prices. Как можно этого избежать?
!!! Проблема именно в не уникальных индексов потому что с другими таблицами связка идет на ура. | |
|
|
|
|
|
|
|
для: daniel20
(12.12.2011 в 19:43)
| | 1. А можно еще EXPLAIN-схему запроса увидеть?
2. InnoDB специально используете? Можно услышать причины? Или вам все-равно, если да, то переведите лучше в MyISAM - там индексы отдельные, а в InnoDB они физические, причем первым идет первичный ключ, у вас ведь по сути не два отдельных ключа, как вам, возможно кажется, у вас один ключ по двум столбцам. InnoDB - это такой очень странный тип таблицы, её бы хорошо саму знать, чтобы с ней работать и базу данных под неё желательно целиком настраивать (так чтобы там вообще MyISAM таблиц практически не было).
PS Если лень/не интересно, на второй вопрос можно не отвечать :))) | |
|
|
|
|
|
|
|
для: cheops
(12.12.2011 в 20:26)
| |
1 SIMPLE ip index (null) IX_prc_items_prices 18 (null) 60203 Using where; Using index; Using temporary; Using filesort
1 SIMPLE i eq_ref PRIMARY PRIMARY 4 price.ip.items_id 1 Using index
|
На счет INNODB - мой шеф приказал везде использовать транзакции. С ним не поспоришь. | |
|
|
|
|
|
|
|
для: daniel20
(13.12.2011 в 11:56)
| | Вот смотрите что происходит, в случае IX_prc_items_prices - происходит полный скан таблицы (60203 строки), причем таблица сбрасывается на диск, сортировка будет обычная без использования индекса, в случае price.ip.items_id - все отлично, данные даже не затрагиваются в этом запросе, MySQL обходится индексами. | |
|
|
|
|
|
|
|
для: cheops
(13.12.2011 в 13:43)
| | Блин. Но как сделать сортировку быстрой? вот запрос:
SELECT
`i`.`items_id`
, `ip`.`new_price`
FROM
items i
INNER JOIN `items_prices` AS `ip`
ON i.items_id = ip.items_id AND is_current_price = 1
GROUP BY
`ip`.`items_id`
ORDER BY
`ip`.`new_price` ASC
LIMIT
4
|
пробовал создать индекс: `ip`.`items_id`,`ip`.`new_price`. Ничего не дает. | |
|
|
|
|
|
|
|
для: daniel20
(13.12.2011 в 15:07)
| | Попробуйте для начала так (только скорости реально замеряйте - стало быстрее или медленее)
SELECT
`i`.`items_id`
, `ip`.`new_price`
FROM
items i
INNER JOIN
(SELECT * FROM `items_prices`
WHERE is_current_price = 1) AS `ip`
ON i.items_id = ip.items_id
GROUP BY
`ip`.`items_id`
ORDER BY
`ip`.`new_price` ASC
LIMIT
4
|
| |
|
|
|
|
|
|
|
для: cheops
(13.12.2011 в 15:36)
| | запуск 3 раза моего запроса: 0.177, 0.177, 0.178
запуск 3 раза вашего запроса: 0.600, 0.618, 0.612
немножко оптимизировал ваш запрос (поменял * на items_id, new_price)
запуск 3 раза данного запроса: 0.179, 0.191, 0.186
Еще забыл сказать, поменял эти две таблицы с InnoDB на MyIsam. Запустил этот запрос, работает медленее. Наверно Mysql settings не оптимизировал под MyIsam, а то ничего другого не приходит в голову. Ожидал более обыстрой работы. | |
|
|
|
|
|
|
|
для: daniel20
(13.12.2011 в 16:33)
| | >Еще забыл сказать, поменял эти две таблицы с InnoDB на MyIsam. Запустил этот запрос,
>работает медленнее. Наверно Mysql settings не оптимизировал под MyIsam, а то ничего другого не
>приходит в голову. Ожидал более обыстрой работы.
Если сервер под InnoDB заточен, MyISAM и не будет быстро работать, у этого типа таблиц скорее всего все отрезано и отдано InnoDB. Насколько я понял, ответ на второй вопрос, перефразируя вашего шефа "ничего не трогайте, все под InnoDB сконфигурировано". | |
|
|
|
|
|
|
|
для: daniel20
(13.12.2011 в 16:33)
| | Повесьте индекс на is_current_price - меняется ли скорость запроса? После этого, если не сложно приведите EXPLAIN - сколько записей перелопачивается во внутреннем запросе? | |
|
|
|
|
|
|
|
для: cheops
(13.12.2011 в 17:53)
| | Вооо, что делает уставшая голова: смотро, индексы уже стояли IX_prc_items_prices(items_id, is_current_price, new_price) запускаю: 0.17 мин. Думаю давай создам индексы по отдельности (выше группа идет) старый индекс удалил и создал по отдельности. Выполняю: 0.2сек. - это логично. Удаляю эти и делаю все как было. Выполняю: 0.058сек. Как так? сам не понял. Пора домой пойти..... | |
|
|
|
|
|
|
|
для: daniel20
(13.12.2011 в 18:52)
| | Хм... судя по всему таблички время от времени чинить/проверять нужно... ну или так вот (удалить, снова создать). | |
|
|
|