Вопрос: если у меня есть таблица Orders
с индексом (UserId, CreatedTime)
, имеет ли значение добавление DESC
к CreatedTime
, если я хочу перечислить заказы только одного пользователя?
Например:
SELECT *
FROM Orders -- Also potentially have row limit
WHERE UserId = @UserId
ORDER BY CreatedTime DESC;
Чего я не понимаю, так это того, что если ответ положительный, то почему БД не может просто начать снизу и идти вверх, поскольку она уже знает диапазон @UserId
?
Кроме того, я работаю как с SQL Server, так и с SQLite, поэтому мне было бы интересно узнать, будет ли ответ отличаться для каждой СУБД.
Я до сих пор не очень понимаю Индексы SQL Server - по возрастанию или по убыванию, какая разница? и, видимо, в MongoDB, это не имеет значения (Имеет ли значение порядок индексов в MongoDB?).
Возвращаясь к приведенному выше запросу, даже если бы мне пришлось перечислить всех пользователей и соответствующие им порядки в порядке убывания CreatedTime
, почему база данных не может сделать это:
Я даже спросил у ИИ, и он просто сказал мне, что извлечение снизу вверх происходит медленнее, без дальнейших объяснений, даже когда я пытался нажать на него.
🤔 А знаете ли вы, что...
SQL Server активно развивается и обновляется Microsoft с выпуском новых версий и обновлений с новыми возможностями и улучшениями.
В SQLite индекс будет использоваться независимо от того, сортируете ли вы по CreatedTime по возрастанию или убыванию.
Данный:
create table orders (
user_id integer,
created_time integer
);
create index orders_index on orders (user_id, created_time);
Планы запросов для обоих типов идентичны:
sqlite> explain query plan select * from orders where user_id = 1 order by created_time;
QUERY PLAN
`--SEARCH orders USING COVERING INDEX orders_index (user_id=?)
sqlite> explain query plan select * from orders where user_id = 1 order by created_time desc;
QUERY PLAN
`--SEARCH orders USING COVERING INDEX orders_index (user_id=?)
Если вместо этого вы выполняете запрос диапазона по user_id, а затем сортируете по user_id, created_time
, дополнительная временная таблица будет использоваться только в том случае, если created_time
отсортировано в порядке убывания:
sqlite> explain query plan select * from orders where user_id > 1 order by user_id, created_time;
QUERY PLAN
`--SEARCH orders USING COVERING INDEX orders_index (user_id>?)
sqlite> explain query plan select * from orders where user_id > 1 order by user_id, created_time desc;
QUERY PLAN
|--SEARCH orders USING COVERING INDEX orders_index (user_id>?)
`--USE TEMP B-TREE FOR LAST TERM OF ORDER BY
Для этого запроса вам понадобится индекс для created_time desc
:
create index orders_index_2 on orders (user_id, created_time desc);
=>
sqlite> explain query plan select * from orders where user_id > 1 order by user_id, created_time desc;
QUERY PLAN
`--SEARCH orders USING COVERING INDEX orders_index_2 (user_id>?)