Какой из следующих запросов будет более быстрым и оптимальным (и почему):
-
SELECT * FROM items WHERE w = 320 AND h = 200
(w и h - INT) -
SELECT * FROM items WHERE dimensions = '320x200'
(размеры - VARCHAR)
Какой из следующих запросов будет более быстрым и оптимальным (и почему):
SELECT * FROM items WHERE w = 320 AND h = 200
(w и h - INT)
SELECT * FROM items WHERE dimensions = '320x200'
(размеры - VARCHAR)
Вот некоторые фактические измерения. (Использование SQLite, возможно, попробует его с MySQL позже.)
Данные = все 1,000,000 комбинаций w, h ∈ {1... 1000} в рандомизированном порядке.
CREATE TABLE items (id INTEGER PRIMARY KEY, w INTEGER, h INTEGER)
Среднее время (20 прогонов) для выполнения SELECT * FROM items WHERE w = 320 and h = 200
составляло 5,39 ± 0,29 мкс.
CREATE TABLE items (id INTEGER PRIMARY KEY, dimensions TEXT)
Среднее время выполнения SELECT * FROM items WHERE dimensions = '320x200'
составляло 5,69 ± 0,23 мкс.
Нет существенной разницы, эффективности.
Существует огромная разница в плане удобства использования. Например, если вы хотите рассчитать площадь и периметр прямоугольников, двухколоночный подход прост:
SELECT w * h, 2 * (w + h) FROM items
Попробуйте написать соответствующий запрос другим способом.
Вероятно, единственный способ узнать, что это за запуск. Я бы заподозрил, что если все используемые столбцы будут проиндексированы, в принципе не будет никакой разницы. Если INT составляет 4 байта, он будет почти того же размера, что и строка.
Одна морщина в том, как хранится VARCHAR. Если вы использовали постоянный размер строки, это может быть быстрее, чем VARCHAR, но в основном потому, что ваш select *
должен получить его.
Огромное преимущество использования INT заключается в том, что вы можете выполнять гораздо более сложную фильтрацию. Это само по себе должно быть основанием для предпочтения. Что делать, если вам нужен диапазон или просто ширина, или вы хотите использовать математику по ширине в фильтрации? Как насчет ограничений на основе столбцов или агрегатов?
Кроме того, когда вы получаете значения на свой язык программирования, вам не нужно будет разбирать их перед их использованием (что требует времени).
EDIT: некоторые другие ответы указывают на сравнение строк. Если проиндексировано, не будет проведено много сравнений строк. И возможно реализовать очень быстрые алгоритмы сравнения, которые не должны зацикливаться по байтам. Вам нужно будет узнать подробности о том, что действительно знает mysql.
Интуитивно, если вы не создаете INDEX
es в этих столбцах, сравнение по целям выглядит быстрее.
В целых сравнениях вы сравниваете прямое 32-битное равенство значений с логическими операторами.
С другой стороны, строки представляют собой массивы символов, их будет сложно сравнивать. Характер за символом.
Однако, еще один момент заключается в том, что во втором запросе у вас есть 1 поле для сравнения, в 1-м запросе у вас есть 2 поля. Если у вас есть 1 000 000 записей и индексов в столбцах, это означает, что у вас может быть 1 000 000 сопоставлений строк в худшем случае (к несчастью, последний результат - это то, что вы искали или не нашли вообще)
С другой стороны, у вас есть 1,000,000 записей, а все w=320
, тогда вы будете сравнивать их и для h
. Это означает 2 000 000 сравнений. Однако вы создаете ИНДЕКСЫ в тех полях ИМХО, они будут почти одинаковыми, поскольку VARCHAR будет хэширован (принимает O(1)
постоянное время) и будет сравниваться с использованием сравнения INT и занимает O(logn)
время.
Заключение, это зависит. Предпочитают индексы на столбцах, доступных для поиска, и используют ints.
Второй запрос, поскольку шансы на соответствие точной строке меньше (что означает меньший набор записей, но с большей мощностью)
Первый запрос, вероятность совпадения первого столбца выше, и больше строк могут быть сопоставлены (меньшая мощность)
конечно, предполагая, что индекс определен для обоих сценариев
сначала, потому что быстрее сравнивать числовые данные.
Это зависит от данных и доступных индексов. Но версия VARCHAR вполне возможна быстрее, потому что поиск одного индекса может быть быстрее, чем два. Если комбинация значений дает уникальный (или "главным образом" уникальный) результат, в то время как каждое отдельное значение H/W имеет несколько записей, то оно может сузить вниз до гораздо меньшего набора, используя единственный индекс.
С другой стороны, если у вас есть индекс с несколькими столбцами в столбцах с целым числом, это, вероятно, будет наиболее эффективным.