Разница в производительности SQL-запросов - PullRequest
3 голосов
/ 26 марта 2012

У меня есть таблица с 1 миллионной записью, и я спроектировал 2 запроса.

индекс таблицы:

id = primary
bedroom = index
elevator = index
pricemeter = index
dateadd = index

Я хочу знать, почему этот запрос:

SELECT 
    *
FROM (
    SELECT 
        * 
    FROM `p_apartmentbuy` 
    WHERE
        `sqm` > 100
        AND `bedroom` > 1
        AND `elevator` = 1
        AND `pricemeter` < 5999999
    ORDER BY `id` DESC
    LIMIT 0, 30
) AS `alias`
ORDER BY `id` DESC, `dateadd` DESC

Это намного быстрее, чем этот:

SELECT 
    * 
FROM `p_apartmentbuy` 
WHERE
    `sqm` > 100
    AND `bedroom` > 1
    AND `elevator` = 1
    AND `pricemeter` < 5999999
ORDER BY `id` DESC, `dateadd` DESC
LIMIT 0, 30

Первый запрос занял 0,0027 с, а второй запрос - 5,6848 с.Оба результата совпадают с другими, и переменные в предложении where являются примерами.

EXPLAIN для быстрого запроса: enter image description here

EXPLAIN для медленного запроса: enter image description here

Ответы [ 4 ]

2 голосов
/ 26 марта 2012

Второй запрос должен отсортировать весь набор данных по id и dateadd, прежде чем он сможет применить лимит.

Первый запрос, с другой стороны, возвращает рано только с 30 записями, которые затемотсортировано по id и dateadd.Гораздо меньше работы.

2 голосов
/ 26 марта 2012

Что ж, нам нужно больше информации об индексах, но простой взгляд на эти запросы показывает, что они разные. Они могут также давать разные результаты, просто совпадение, что они одинаковы (скорее всего, исходя из того, как структурированы ваши данные). В первом запросе вы выбираете 30 строк, упорядочивая их по id (у которых может быть индекс), а затем сортирует их по dateadd, что довольно просто. Ваш второй запрос должен отсортировать все ваши миллионные записи по этим двум столбцам, а затем выбрать 30, так что он явно будет дороже.

1 голос
/ 26 марта 2012

Объяснение подтвердит

Но первая получает первые 30 записей по идентификатору, который, предположительно, является первичным ключом, и поэтому Order by id не требует сортировки.Затем сортировка только этих 30.

В то время как вторая, получает все записи в произвольном порядке, затем сортирует их по идентификатору и дате, а затем берет первые 30 ...

Индексна dateadd, может быть?

Только образованное предположение.

0 голосов
/ 26 марта 2012

Ваша таблица должна использовать ID в качестве первичного ключа. В этом случае строки индексируются с помощью столбца ID, а все данные уже упорядочены по идентификатору.

Итак, первые 30 строк - это быстро для плана mysql. затем закажите эти 30 рядов, они будут быстрыми.

Второй запрос должен вернуть все строки, чтобы отсортировать их по столбцу dateadd. Затем будет рассчитано предложение LIMIT.

Надеюсь, это ответит на ваш вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...