MySQL как хранилище с упорядоченным значением ключа

Документы говорят, что:

Большинство индексов MySQL (PRIMARY KEY, UNIQUE, INDEX и FULLTEXT) хранятся в B-деревьях.

Так что физически данные уже отсортированы по ключу. Мне нужна схема ключ-значение в MySQL с поддержкой запроса диапазона: SELECT key, value FROM MyTable WHERE key >= key1 and key < key2;

Во многих (большинстве) примерах в Интернете я вижу, что люди добавляют ORDER BY даже при выборе по первичному ключу.

Мои вопросы:

  • Действительно ли здесь нужен ORDER BY, чтобы всегда сортировать результаты, и если да, то почему?
  • Повлияет ли сортировка на производительность или она будет оптимизирована?
  • Имеет ли смысл делать значения частью составного индекса, если они не слишком велики, например. просто цифры?
  • Будет ли SELECT key, value FROM MyTable WHERE key > key1 LIMIT 1; возвращать следующий ключ, больший, чем key1, или любой ключ, больший, чем key1? Как надежно получать LT,LE,GT,GE точечные запросы?

(Мне это нужно в MySQL по почти «политическим» и инструментальным причинам, прежде чем переходить на другое существующее хранилище KV на основе B +-дерева, я уже выбрал лучший LMDB, поэтому вопросы касаются только имитации схемы в MySQL)


person V.B.    schedule 23.03.2015    source источник
comment
Если это в сети, это должно быть правдой ;)   -  person nomistic    schedule 23.03.2015
comment
@номистический сарказм? :) Погуглив и увидев множество примеров, мне действительно нужна проверка на работоспособность.   -  person V.B.    schedule 23.03.2015
comment
Я здесь не эксперт, поэтому я не буду отвечать на вопрос, но применение порядка всегда должно иметь нейтральный или отрицательный эффект на этот запрос. В неиндексированном столбце сортировка в лучшем случае всегда O (n log n), в то время как фактическая проверка каждой записи при полном сканировании таблицы будет O (n). В индексированном столбце, хранящемся в B-Tree, сортировка не будет иметь никакого эффекта, если в нем используется тот же оператор сравнения, и негативный эффект, если будет использоваться другой.   -  person Nick Bailey    schedule 23.03.2015
comment
Да, прости. Я понимаю первую часть так, что это делается по привычке и хорошей практике кодирования (это имеет смысл, если это не первичный ключ). Кроме того, иногда первичный ключ не является числовым (например, тип переменной type_code... Я часто использую их для таблиц с некоторым уровнем контроля, чтобы ускорить выполнение запросов, но в этом случае я обычно упорядочиваю по значение, а не код). Я иногда заказываю по две записи. Извините, я не знаю о производительности, но я предполагаю, что она минимальна. Понятия не имею о последней части.   -  person nomistic    schedule 23.03.2015


Ответы (1)


  • #P1#
    #P2# #P3#
  • #P4#
    #P5# #P6# #P7#
  • #P8#
    #P9# #P10#
  • #P11#
    #P12# #P13#
    SELECT key, value FROM MyTable WHERE key > key1 ORDER BY key LIMIT 1
    
    #P14#
    SELECT key, value FROM MyTable WHERE key <= key1 ORDER BY key DESC LIMIT 1
    
person eggyal    schedule 23.03.2015
comment
Благодарю вас! Сначала мне нужна правильность - чтобы значения всегда сортировались по ключу (я обновил вопрос и добавил еще один подвопрос - не могли бы вы прокомментировать 4-й, пожалуйста?). В то же время я не хочу наделать глупостей, чтобы во время запроса испортился существующий порядок B-дерева и мне пришлось заново применять ORDER BY с его накладными расходами. Этот макет в основном для времени разработки, но объем данных пока не такой большой, и MySQL может хватить на долгое время, мне просто нужно скрыть хранилище за интерфейсом и получить точно такое же поведение, как обычное B-дерево. Как ни странно, MySQL скрывает это. - person V.B.; 23.03.2015
comment
Круто, спасибо большое! Просто из любопытства: для 4-го пункта, вы думаете, что, например. InnoDB, оптимизатор достаточно умен, чтобы просто выполнять бинарный поиск и переходить к следующему/предыдущему вместо того, чтобы выбирать все ключи больше/меньше, затем сортировать их, а затем брать первый? Или EXPLAIN покажет и это? - person V.B.; 23.03.2015
comment
@V.B.: См. раздел Оптимизация LIMIT-запросов — если вы объедините LIMIT row_count с ORDER BY , MySQL заканчивает сортировку, как только находит первые row_count строки отсортированного результата, а не сортирует весь результат. Если упорядочивание выполняется с использованием индекса, это очень быстро... Как только MySQL отправит клиенту необходимое количество строк, он прерывает запрос, если только вы не используете SQL_CALC_FOUND_ROWS. - person eggyal; 23.03.2015