заказ по полю с более чем 10000 идентификаторами - PullRequest
1 голос
/ 19 мая 2011

Мне нужно сделать конкретный заказ с использованием заказа по полю.

select * from table order by field(id,3,4,1,2.......upto 10000 ids)

Поскольку требуемый порядок нельзя получить из SQL, то насколько он влияет на производительность и выполнимо ли это сделать?

Обновления от комментариев:

  • Заказ зависит от идентификаторов пользователей и категорий и может быть любым, что хочет пользователь.
  • Спецификация заказа меняется (примерно) ежедневно.

Итак, нам нужен индивидуальный заказ, который зависит от пользователя и категории, и этот заказ должен меняться ежедневно.

1 Ответ

4 голосов
/ 19 мая 2011

Самым простым способом было бы поместить ваш заказ в отдельную таблицу (в данном примере называемую ordering_table):

 id | position
----+----------
  1 | 11
  2 | 42
  3 | 23
 etc.

Вышеуказанное означало бы "поставить id из 1 в позицию 11, 2 в положении 42, 3 в положении 23, ... ".Затем вы можете присоединиться к этой таблице заказов в:

SELECT t.id, t.col1, t.col2
FROM some_table t
JOIN ordering_table o ON (t.id = o.id)
ORDER BY o.position

Где ordering_table - таблица (как указано выше), которая определяет ваш странный порядок.Этот подход просто представляет вашу функцию упорядочения в виде таблицы (в конце концов, любая функция с конечной областью, по сути, является просто таблицей).

Этот подход «таблицы упорядочения» должен работать нормально, пока таблица упорядочениязавершено.

Если вам нужен только этот странный порядок в одном месте, вы можете объединить столбец position в основную таблицу и добавить ограничения NOT NULL и UNIQUE для этого столбца, чтобы убедиться, что вы охватите всеи иметь последовательный порядок.

Дальнейшее комментирование означает, что вы хотите разные заказы для разных пользователей и категорий и что порядок будет меняться ежедневно.Вы можете создать отдельные таблицы для каждого условия (что может привести к комбинаторному взрыву) или, как советуют Микаэль Эрикссон и ypercube, добавить еще пару столбцов в таблицу заказов для хранения пользователя и категории:

CREATE TABLE ordering_table (
    thing_id    INT NOT NULL,
    position    INT NOT NULL,
    user_id     INT NOT NULL,
    category_id INT NOT NULL
);

thing_id, user_id и category_id будут внешними ключами для их соответствующих таблиц, и вы, вероятно, захотите проиндексировать все столбцы в ordering_table, но стоит несколько минут посмотреть на планы запросов.чтобы увидеть, будут ли индексы привыкать, стоило бы.Вы также можете сделать все четыре столбца первичным ключом, чтобы избежать дублирования.Тогда запрос поиска будет выглядеть примерно так:

SELECT t.id, t.col1, t.col2
FROM some_table t
LEFT JOIN ordering_table o
     ON (t.id = o.thing_id AND o.user_id = $user AND o.category_id = $cat)
ORDER BY COALESCE(o.position, 99999)

Где $user и $cat - идентификаторы пользователя и категории (соответственно).Обратите внимание, что изменение в LEFT JOIN и добавление COALESCE, позволяющее пропустить строки в ordering_table, эти изменения будут помещать все, что не имеет указанной позиции в порядке, в конец списка, вместо того, чтобы удалять их изрезультаты полностью.

...