
![]() |
Здравствуйте Гость ( Вход | Регистрация ) |
|
|
|
![]() ![]() ![]() |
![]() |
۩
Дата
|
||
![]() ![]() Здесь живет ![]() ![]() ![]() ![]() ![]() ![]() Профиль Группа: Форумчанин ![]() Сообщений: 406 Пользователь №: 23841 На форуме: Карма: 22 ![]() |
Добрый день. Не знаю, не могу разобраться с глупой проблемой. Почему не используется индех при элементарной выборке? Структура таблицы:
Запрос: explain select * from sc_webdata_main order by price desc limit 300, 10; Результат:
Не понимаю почему по-умолчанию не используется индех (ix_price) и mysql сканирует все записи? С таким вариантом выглядит лучше: explain select * from sc_webdata_main force index (ix_price) order by price desc limit 3000, 1 Результат: +----+-------------+-----------------+-------+---------------+----------+---------+------+------+---- ---+ Можно ли как-то обойтись без force index и почему даже если используется индекс - сканируются 3000 тыс. строк вместо 10? или я не совсем понимаю принцип работы... -------------------- |
||
![]() |
|
![]() ![]() Здесь живет ![]() ![]() ![]() ![]() ![]() ![]() Профиль Группа: Форумчанин ![]() Сообщений: 2804 Пользователь №: 24406 На форуме: Карма: 181 ![]() |
ПО умолчанию, Mysql, за редким исключением, очень тупо применяет(или не применяет) индекс к сортируемым полям. Честно говоря буквально пару раз в своей жизни видел, чтобы Mysql нормально применил индекс к сортируемому полю.
Понятное дело, там шуршит анализатор, оптимизатор, которые принимают решения по целесообразности той или иной стратегии выполнения запроса, но блин, эти решения однобоки)) -------------------- Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
|
![]() |
|||
![]() ![]() TERRAFORMING ENGINEER ![]() ![]() ![]() ![]() ![]() ![]() Профиль Журнал Группа: ★ЛжеЭксперт★ ![]() Сообщений: 3900 Пользователь №: 21196 На форуме: Карма: 88 ![]() |
Тоже хотел что-то подобное написать, но постеснялся. Есть таблица на сайте к которой применяет (там участвует WHERE), а в другой не применяет, так и не понял почему. -------------------- Не тот велик, кто не падал, а тот кто падал и поднимался.
|
||
![]() |
۩
Дата
|
![]() ![]() Здесь живет ![]() ![]() ![]() ![]() ![]() ![]() Профиль Группа: Форумчанин ![]() Сообщений: 406 Пользователь №: 23841 На форуме: Карма: 22 ![]() |
ОК. Понятно, значит буду использовать конструкцию с "force index" (см. 2ой пример). Но такой вопрос. Если offset будет стоять 1 миллион, то он сначала переберет 1 миллион записей, а потом вернет 10 требуемых? Нельзя ли как-то оптимизировать этот процесс?
-------------------- |
![]() |
|||
![]() ![]() Сидел он, дум великих полон - и вдаль глядел ![]() ![]() ![]() ![]() ![]() ![]() Профиль Группа: Эксперт ![]() Сообщений: 15860 Пользователь №: 4190 На форуме: Карма: 490 ![]() |
А ты как хотел? Всё очень логично получается. Откуда запрос может узнать, какие именно 3000 записей пропустить? Только из того, что их перебрать. Так что то, что ты описал, это нормальная работа limit в БД. Оптимизировать можно, но не во всех случаях. Например, если ты знаешь, какое у тебя было предыдущее значение, например, по полю price (в предыдущей подобной выборке, допустим при постраничной навигации, пусть это было число 1436.78). Тогда ты можешь написать так select * from sc_webdata_main При таком запросе будет обработана всего одна строка. Но это, как я уже сказал, "особый случай". Можно попробовать выбрать этот порог подзапросом с лимитом "3000, 1", но там выбирать не всё, а только одно поле. Возможно, что это будет сделано быстрее (потому что в подзапросе будет выбираться существенно меньше данных). Но надо проверить, какая будет скорость. select * from sc_webdata_main -------------------- * Хэлп по PHP
* Описалово по JavaScript * Хэлп и СУБД для PostgreSQL * Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги. * "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С) ![]() |
||
![]() |
![]() ![]() ![]() |