
当一个查询中包含较多的”碰撞性很高的列”的时候,如何优化呢?
比如有如下 SQL:
SELECT * FROM tab WHERE status=1 AND is_Onsale=1 AND type=1 AND is_recommand
类似这样的查询,假设这里的查询条件的可能值都只有少数几个, 如 status 的值只能为 1,2,3。is_onsale 的值只能为 1 或 -1。
1 geeglo 2017-08-29 10:45:03 +08:00 你好像拼错单词了 |
2 silenceeeee OP @geeglo ... |
3 zjm947373 2017-08-29 11:05:12 +08:00 …… where status in (1,2,3) and is_onsale in (1,-1)…… |
4 silenceeeee OP @zjm947373 可能我没有描述清楚,我的意思是 status 的值可能是 1 或者 2 或者 3,但是查询的时候是查的一个明确的条件,比如 status=1,或者 status=2 |
5 cye3s 2017-08-29 12:05:34 +08:00 via Android mysql 有 bitmap 索引么? |
6 zjm947373 2017-08-29 12:10:22 +08:00 @silenceeeee 这个不就是 in 的作用么。。。至于查询条件不是应该由你的程序来生成的么,要查 1 或 2 生成的自然就是 in (1,2)了。(或者我真没看懂你到底是在问什么) |
7 silenceeeee OP @zjm947373 查询条件:WHERE status=xxx (查询的时候没有使用 OR 和 IN 的需求)我称之为“但是查询的时候是查的一个明确的条件 比如 status=1,或者 status=2 ” status 的值可能是 1 或者 2 或者 3: status 的值可以(且只能)是 1, 2, 3 的其中一项。 |
8 finull 2017-08-29 14:08:39 +08:00 |
9 fcka 2017-08-29 14:20:03 +08:00 via Android 这个表有多少万行? |
10 silenceeeee OP |
11 kkeiko 2017-08-29 14:57:51 +08:00 mysql 的组成中有一部分叫‘查询优化器’,类似编译优化,就是你输入的语句其实不一定是最终执行的语句,mysql 自己会进行优化。你的这个问题就直接该怎么写就怎么写呗,where ... and ... and ... 只要每列都建索引了,这么写就是最优方案了。 |
12 floraX 2017-08-29 15:00:28 +08:00 |
13 kkeiko 2017-08-29 15:04:21 +08:00 @floraX 可能是我表达问题,我的意思是说该查的列都建上索引就行了,当然具体你 where 一个条件可以建单列索引,多个条件可以建联合索引。核心观点是得有索引 |
14 badttt 2017-08-29 18:37:06 +08:00 按照问题中的查询,只要建了索引就是最大优化,建议了解下 MySQL 中的索引最左前缀匹配 |
15 340244120 2017-08-29 19:30:39 +08:00 via Android 一个字段建好索引后,接着又在另一个联合索引中作为最左的字段。或者这两步顺序反过来。这两种情况下字段会建立两次索引吗 |
16 wintercoder 2017-08-29 21:08:00 +08:00 借楼问,类似的,上面的 status 如果为 1 的值很多,为 2 的很少,为 3 的一般多,limit 20 去查 status=1 的话很快,查 2 很慢,除了索引 还有其他方案么,加索引的话跟已有一起拼成复合的还是单独建好 |
17 wintercoder 2017-08-29 22:02:36 +08:00 @wintercoder #16 额我这种情况区分度不高,建索引也没意义,还是会走全表- - |
18 zhx1991 2017-08-29 22:43:51 +08:00 这种区分度不高的没什么办法, 怎么捣鼓都是全表扫描 只能从别的角度下手, 比如事先算好数扔在缓存里 |
19 akira 2017-08-30 00:09:33 +08:00 没有太好的办法优化的。 最好是另外有一个字段可以上索引 并大幅减少数据。 例如时间维度? |
20 msg7086 2017-08-30 00:58:56 +08:00 recommand 重新发号施令。 |
21 stelpen 2017-08-30 07:50:26 +08:00 via Android @finull 如果这几个值分布均匀索引也没啥效果,如果分布不均匀,查询的值是分布较少的那一部分,索引才有明显的效果 |
22 stelpen 2017-08-30 07:51:09 +08:00 via Android @wintercoder 说反了吧 |
23 viakiba 2017-08-30 08:47:36 +08:00 explain 一下 |
24 caijihui11 2017-08-30 08:58:54 +08:00 不用调整了,这样就是最好的 sql 了 。 |
25 DRcoding 2017-08-30 09:06:28 +08:00 少年郎,你还是买本权威指南看看吧,你这单表查询优化无非是对查询项加索引。对于你说的“碰撞性很高的列”,你没有发现如果你第二次重复执行一条相同的查询语句,一般情况下速度会快很多嘛。 |
26 silenceeeee OP @340244120 会的 这两个索引的最左前缀是不一样的。 |
27 340244120 2017-08-30 18:25:19 +08:00 via Android @silenceeeee 谢谢 不过这也略不智能啊 |