使用大于运算符和ORDER BY的MySQL查询的索引帮助

Jay*_*mon 6 mysql sql database indexing

我有一个至少有几百万行的表和一个看起来大致如下的所有整数的模式:

start
stop
first_user_id
second_user_id
Run Code Online (Sandbox Code Playgroud)

使用以下查询拉取行:

SELECT * 
  FROM tbl_name 
 WHERE stop >= M 
   AND first_user_id=N  
   AND second_user_id=N 
ORDER BY start ASC

SELECT * 
  FROM tbl_name 
 WHERE stop >= M 
   AND first_user_id=N 
ORDER BY start ASC
Run Code Online (Sandbox Code Playgroud)

我无法找出加速这些查询的最佳索引.问题似乎是ORDER BY,因为当我把它拿出来时查询速度很快.

我使用标准索引格式尝试了所有不同类型的索引:

ALTER TABLE tbl_name ADD INDEX index_name (index_col_1,index_col_2,...)
Run Code Online (Sandbox Code Playgroud)

而且他们似乎都没有加快查询速度.有谁知道什么索引可以工作?另外,我应该尝试不同类型的索引吗?我不能保证每一行的唯一性,所以我避免使用UNIQUE索引.

任何指导/帮助将不胜感激.谢谢!

更新:这里是一个索引列表,我最初没有包括这个,因为我采取了猎枪的方法,并添加了大量的索引寻找一个有效的:

start_index: [start, first_user_id, second_user_id]
stop_index: [stop, first_user_id, second_user_id]
F1_index: [first_user_id]
F2_index: [second_user_id]
F3_index: [another_id]
test_1_index: [first_user_id,stop,start]
test_2_index: [first_user_id,start,stop]
test_3_index: [start,stop,first_user_id,second_user_id]
test_4_index: [stop,first_user_id,second_user_id,start]
test_5_index: [stop,start]
Run Code Online (Sandbox Code Playgroud)

这是EXPLAIN输出.

*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: listing
type: index_merge
possible_keys: stop_index,F1_index,F3_index,test_1_index,test_2_index,test_4_index,test_5_index
key: F1_index,F3_index
key_len: 5,5
ref: NULL
rows: 238
Extra: Using intersect(F1_index,F3_index); Using where; Using filesort
Run Code Online (Sandbox Code Playgroud)

后人更新

我们最终完全重新评估了我们如何查询表并选择了这些索引:

index_select_1: [first_user_id,start,stop]
index_select_2: [first_user_id,second_user_id,start,stop]
Run Code Online (Sandbox Code Playgroud)

然后我们在桌面上选择这样的查询:

SELECT * 
  FROM tbl_name 
 WHERE first_user_id=N
   AND start >= M 
ORDER BY start ASC

SELECT * 
  FROM tbl_name 
 WHERE first_user_id=N   
   AND second_user_id=N
   AND start >= M 
ORDER BY start ASC
Run Code Online (Sandbox Code Playgroud)

感谢所有回答的人,你真的帮助我思考问题.

mal*_*nso 0

尽量避免使用范围(例如 >、>=、<、<=)作为 WHERE 子句的最左侧部分。MySQL 无法对 WHERE 子句中范围右侧的任何字段使用索引。

乍一看,我会说至少在first_user_id、stop、second_user_id 上创建一个索引。然后相应地指定查询:

select * from tbl_name where first_user_id=N and stop >= M and secondary_user_id=N

更新:哦,所以我在上面的查询中完全矛盾了 - 因为在停止“范围”之后的 WHERE 中指定它时,将 secondary_user_id 合并到索引中是没有用的,所以让我们再试一次。

ALTER TABLE tbl_name ADD INDEX index_1 (first_user_id,stop) ALTER TABLE tbl_name ADD INDEX index_2 (first_user_id,second_user_id,stop)