Без прохождения всей таблицы в SQL, выборка последних N записей, вставленных после заданной отметки времени [дубликат]

Как и при вводе вкладок в текстовом редакторе, символ табуляции увеличивает длину до следующего кратного 8.

Итак:

  • '\ t' само по себе является 8, очевидно.
  • '\ t \ t' равно 16.
  • 'abc \ tabc ' начинается с 3 символов, затем вкладка подталкивает его до 8, а затем последний ' abc ' отталкивает его от 8 до 11 ...
  • 'abc \ tabc \ tabc' также начинается с 3, вкладка удаляет его до 8, другой 'abc' переходит в 11, затем другая вкладка подталкивает его к 16 и конечный 'abc' доводит длину до 19.
3
задан kent ilyuk 6 September 2012 в 23:17
поделиться

3 ответа

Причина заключается в различии между двумя запросами:

  • Ваш первый запрос никогда не коснется таблицы - он будет полагаться только на индекс
  • . Второй запрос на самом деле необходимо поразить все строки

Итак, чтобы вернуться к более оптимальному первому случаю, вам нужен индекс, который может обеспечить как: группировку по cid, так и min / maxing id. Вы можете попытаться добиться этого, создав индекс (cid, id)

4
ответ дан Eugen Rieck 15 August 2018 в 16:47
поделиться
  • 1
    Спасибо. Я сделал то, что вы сказали, и добавил индекс (cid, id). Теперь у меня есть 3 индекса id (PK), (cid, id) и cid. Запрос теперь занимает 0.0085 сек. У меня есть другой вопрос относительно вашего подхода. Не работает ли id (PK) в качестве индекса здесь? Отдельный индекс cid, который я создал ранее, нужен или бесполезен? Всем спасибо. – kent ilyuk 6 September 2012 в 23:52
  • 2
    ключ на id может использоваться или не использоваться (см. EXPLAIN SELECT ...), но в любом случае он должен быть запрошен дважды для каждого cid. Комбинированный ключ обеспечивает однократный поиск с отличной локальностью: записи, которые вы используете, будут близки друг к другу, часто на одной странице, поэтому никаких дополнительных операций ввода-вывода не требуется. Ключ на cid не нужен для этого запроса - вы должны удалить его, если другие запросы не полагаются на него, чтобы ускорить время вставки – Eugen Rieck 6 September 2012 в 23:55
  • 3
    Я понял, что вы имеете в виду. Я сделаю еще один тест, чтобы посмотреть, как он будет работать. Для ключа cid при условии, что существует только одно условие where cid = 15; (cid,id), или я должен сохранить cid тоже? – kent ilyuk 7 September 2012 в 00:00
  • 4
    (Хорошее) эмпирическое правило: составной индекс является идеальной заменой для его первой части. Таким образом, (cid,id) должна быть идеальной заменой cid. Там могут быть краевые случаи с большими таблицами и низкой ОЗУ: составной индекс может помещать меньше строк на одну индексную страницу, поэтому вам нужно больше страниц индекса для поиска. Это может замедлить использование составного индекса a.o.t одного индекса столбца, но опять же: это краевой случай. – Eugen Rieck 7 September 2012 в 00:03
  • 5
    Огромное спасибо. Можете ли вы предложить мне какие-нибудь книги или источники, где я могу изучить эти советы или правила MySQL? Или mysql.com - мой лучший друг? – kent ilyuk 7 September 2012 в 00:12

Я бы попробовал добавить составной индекс для cid и id. Это могло бы заменить существующий индекс только на cid. Я предлагаю вам просмотреть некоторые типичные запросы для оценки влияния увеличения размера существующего индекса. Компонентный индекс содержит точно данные, необходимые для удовлетворения запроса, поэтому необходимо свести к минимуму требуемую работу.

MySQL использует оптимизацию на основе затрат. Расчет стоимости основан на размере ввода-вывода, поэтому, если вы можете ввести индекс только для интересующих столбцов, это должно минимизировать количество операций ввода-вывода и привести к оптимальному запросу.

1
ответ дан martin clayton 15 August 2018 в 16:47
поделиться
  • 1
    Согласен. Кажется, это один из немногих вариантов. Другой возможностью было бы разделение на cid; это может значительно ускорить запрос, если число различных значений в cid довольно мало по сравнению с общим размером таблицы. С этим разделением на месте потребуется только индекс для идентификатора. – Roland Bouman 6 September 2012 в 23:22

Посмотрите, что в руководстве mysql говорится об ускорении запроса max (), min ()

MySQL использует индексы для этих операций:

Чтобы найти MIN () или MAX () для определенного индексированного столбца key_col. Это оптимизируется препроцессором, который проверяет, используете ли вы WHERE key_part_N = constant во всех ключевых частях, которые происходят до key_col в индексе. В этом случае MySQL выполняет один ключевой поиск для каждого выражения MIN () или MAX () и заменяет его константой.

0
ответ дан NIlesh Sharma 15 August 2018 в 16:47
поделиться
  • 1
    Кажется, это не имеет значения для этого конкретного запроса? – Roland Bouman 6 September 2012 в 23:22
Другие вопросы по тегам:

Похожие вопросы: