Я понимаю, как ORDER BY
работает пункт и как FIELD()
работает функция. Что я хочу понять, так это то, как они оба работают вместе для сортировки. Как извлекаются строки и как получается порядок сортировки
+----+---------+
| id | name |
+----+---------+
| 1 | stan |
| 2 | kyle |
| 3 | kenny |
| 4 | cartman |
+----+---------+
SELECT * FROM mytable WHERE id IN (3,2,1,4) ORDER BY FIELD(id,3,2,1,4)
Приведенный выше запрос приведет к
+----+---------+
| id | name |
+----+---------+
| 3 | kenny |
| 2 | kyle |
| 1 | stan |
| 4 | cartman |
+----+---------+
что-то похожее на поговорку ORDER BY 3, 2, 1, 4
ВОПРОСОВ
- Как это работает внутри?
- Как MySQL получает строки и вычисляет порядок сортировки?
- Откуда MySQL знает, что он должен сортировать по столбцу id?
SELECT *, FIELD(id,3,2,1,4) AS f FROM mytable WHERE id IN (3,2,1,4);
затем добавьтеORDER BY f
илиORDER BY FIELD(id,3,2,1,4)
и попробуйте снова.Ответы:
Для записи
должно работать так же, потому что вам не нужно упорядочивать список в
WHERE
пунктеЧто касается того, как это работает,
FIELD () - это функция, которая возвращает позицию индекса в списке с разделителями-запятыми, если искомое значение существует.
Эти
ORDER BY
значения вычисляются по какому полю () возвращаетВы можете создавать всевозможные модные заказы
Например, используя функцию IF ()
Это приведет к тому, что первые 4 идентификатора появятся вверху списка, в противном случае он появится внизу. Зачем?
В
ORDER BY
, вы либо получите 0 или 1.Давайте перевернем это с DESC в первом столбце
В
ORDER BY
, вы все равно либо получите 0 или 1.ВАШ АКТУАЛЬНЫЙ ВОПРОС
Если вы серьезно хотите узнать об этом, перейдите на страницы 189 и 192 Книги.
для настоящего глубокого погружения.
По сути, существует класс C ++, который называется
ORDER *order
(ORDER BY
Дерево выражений). InJOIN::prepare
,*order
используется в вызываемой функцииsetup_order()
. Почему в серединеJOIN
класса? Каждый запрос, даже запрос к одной таблице, всегда обрабатывается как JOIN (см. Мой пост. Есть ли разница в выполнении между условием JOIN и условием WHERE? )Исходный код для всего этого
sql/sql_select.cc
Очевидно,
ORDER BY
дерево собирается провести оценкуFIELD(id,3,2,1,4)
. Таким образом, числа 0,1,2,3,4 являются значениями, сортируемыми при переносе ссылки на соответствующую строку.источник
N
значения в обоихIN
иFIELD
. В этом примереN=4
. Правильно ли я понимаю, что этот запрос будет выполнять хотя бы~N^2
операции. Потому что каждоеFIELD
вычисление делает~N
сравнения один раз для каждой строки. Если так, то это довольно медленно для большого.N
Может быть, это не очень хороший подход?FIELD()
Функция должна бытьO(1)
операцией, потому чтоFIELD()
имеет числовой индексid
. Так что я не вижу ничего другого, кроме какO(n)
на основе строк. Я не вижуFIELD()
выполнения какой-либо итерационной операции, такой какGREATEST()
необходимо.FIELD
естьN
аргументы для сравнения, то он выполнитN
сравнения. Как еще можно сравнить одно число сN
другими числами, если не делатьO(N)
? Единственная возможность, о которой я могу думать, - это какая-то оптимизация с помощью специальной структуры данных, такой как хеш или дерево аргументов. На самом деле я знаю, чтоIN
имеет такую оптимизацию. Я не знаю оFIELD
. Что вы подразумеваете под «числовым индексом»?Возможно, это будет слишком далеко от реального кода, поэтому недостаточно низкоуровневый, чем вы хотели:
Когда MySQL не может использовать индекс для извлечения данных в отсортированном порядке, он создает временную таблицу / набор результатов со всеми выбранными столбцами и некоторыми дополнительными данными - один из них является своего рода столбцом для хранения результатов значения выражения ORDER BY для каждой строки - затем он отправляет эту таблицу tmp в процедуру «файловой сортировки» с информацией, по какому столбцу сортировать. После этого строки располагаются в отсортированном порядке, поэтому он может выбрать их одну за другой и вернуть выбранные столбцы.
источник
FIELD
функция вычисляется. Боюсь, это может оказать существенное влияние на производительность.