7

1 -PRIMARY用于二级索引,例如 ( PRIMARY, column1)上的二级索引

2 - 我知道,一旦将一个部分用于范围扫描,mysql就无法继续使用索引的其余部分,但是:IN (...,...,...)不被视为范围,是吗?是的,它是一个范围,但我在 mysqlperformanceblog.com 上读过它的IN行为与BETWEEN索引的使用不同。

谁能证实这两点?或者告诉我为什么这是不可能的?或者怎么可能?

更新:

链接:
http ://www.mysqlperformanceblog.com/2006/08/10/using-union-to-implement-loose-index-scan-to-mysql/
http://www.mysqlperformanceblog.com/2006/08/ 14/mysql-followup-on-union-for-query-optimization-query-profiling/comment-page-1/#comment-952521

更新 2:嵌套 SELECT 的示例:

SELECT * FROM user_d1 uo 
WHERE EXISTS (
    SELECT 1 FROM `user_d1` ui
    WHERE ui.birthdate BETWEEN '1990-05-04' AND '1991-05-04'
    AND ui.id=uo.id
)    
ORDER BY uo.timestamp_lastonline DESC
LIMIT 20

因此,外部SELECT用于timestamp_lastonline排序,内部PK用于与外部连接或birthdate用于过滤。

如果 MySQL 不能在范围扫描和排序中使用索引,那么除了这个查询还有什么其他选项?

4

3 回答 3

2

主键的列当然可以在二级索引中使用,但通常不值得。主键保证唯一性,因此在它之后列出的任何列都不能用于范围查找。唯一有帮助的时候是查询可以单独使用索引

至于您的嵌套选择,额外的复杂性不应超过最简单的查询:

SELECT * FROM user_d1 uo 
WHERE uo.birthdate BETWEEN '1990-05-04' AND '1991-05-04'
ORDER BY uo.timestamp_lastonline DESC
LIMIT 20

MySQL 将根据它认为最有可能扫描更少行的birthdate索引或索引之间进行选择。timestamp_lastonline在任何一种情况下,该列都应该是索引中的第一个。该birthdate索引还将进行排序惩罚,但如果大量近期用户的出生日期超出该范围,则可能是值得的。

如果您希望控制顺序或潜在地提高性能,a (timestamp_lastonline, birthdate)or (birthdate, timestamp_lastonline)index 可能会有所帮助。如果没有,并且您确实需要首先根据生日进行选择,那么您应该从内部查询中进行选择,而不是对其进行过滤:

SELECT * FROM (
    SELECT * FROM user_d1 ui
    WHERE ui.birthdate BETWEEN '1990-05-04' AND '1991-05-04'
) as uo
ORDER BY uo.timestamp_lastonline DESC
LIMIT 20

即使这样,如果 MySQL 的优化器找到timestamp_lastonline索引但没有birthdate索引,它可能会选择重写您的查询。

是的,IN (..., ..., ...)行为不同于BETWEEN. 只有后者可以有效地对索引使用范围扫描;前者会单独查找每个项目。

于 2012-07-03T18:36:11.137 回答
0

2.IN明显不同BETWEEN。如果您对该列有索引,BETWEEN则需要获取起点并且一切都完成了。如果您有,它将按值在索引值中查找匹配值,因此与的一次查找IN相比,它将查找值的次数与有值的次数一样多。BETWEEN

于 2012-06-18T09:21:40.927 回答
0
  1. 是的@Andrius_Naruševičius 是对的IN语句只是EQUALS OR EQUALS OR EQUALS的简写,因为 BETWEEN 是一个隐含大于或小于的比较运算符,因此绝对喜欢索引

  2. 老实说,我不知道你在说什么,但似乎你在问一个很好的问题,我只是不知道它是什么:-)。您是说主键不能包含第二个索引吗?因为它绝对可以。主键永远不需要被索引,因为它总是自动索引,所以如果你收到关于补充索引的错误/警告(我假设你是?)那么它不是第二个,第三个索引导致它是 PRIMARY KEY 不需要它,你提到这可能是错误。话虽如此,我不知道您问了什么问题-这是我对您的实际问题的最佳猜测的回答。

于 2012-06-19T17:15:49.643 回答