如果仅使用 equal 操作查询第一列,数据库复合索引顺序是否重要?

问题描述 投票:0回答:1

(下面有更多上下文)

问题:假设我有一个带有索引

Orders
(UserId, CreatedTime)
表,如果我只想列出单个用户的订单,将
DESC
添加到
CreatedTime
是否重要?

例如:

SELECT * 
FROM Orders -- Also potentially have row limit
WHERE UserId = @UserId
ORDER BY CreatedTime DESC; 

我不明白的是,如果答案是肯定的,为什么数据库不能简单地从底部开始然后向上,因为它已经知道

@UserId
的范围?

我还使用 SQL Server 和 SQLite,所以我很想知道每个 DBMS 的答案是否不同。

我仍然不太明白SQL Server索引 - 升序或降序,它有什么区别?显然在MongoDB中, 没关系(MongoDB 中索引的顺序重要吗?)。

回到上面的查询,即使我要按降序列出所有用户及其对应的顺序

CreatedTime
,为什么数据库不能这样做:

  • 对于用户 #1,他们的行是从 #1 到 #10,因此以相反的顺序获取行 #1 到 #10。
  • 对于用户#2,他们的行是从#11到#13,因此以相反的顺序获取行#11到#13。
  • ...

我什至询问了 AI,它只是告诉我,即使我尝试按下它,从下往上获取的速度也会更慢,而无需进一步解释。

sql-server database sqlite indexing
1个回答
0
投票

在 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
© www.soinside.com 2019 - 2024. All rights reserved.