请教一个 MySQL 查询问题

2017-08-29 09:53:48 +08:00
 silenceeeee

当一个查询中包含较多的”碰撞性很高的列”的时候,如何优化呢?

比如有如下 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。

4517 次点击
所在节点    MySQL
27 条回复
geeglo
2017-08-29 10:45:03 +08:00
你好像拼错单词了
silenceeeee
2017-08-29 11:03:32 +08:00
@geeglo ...
zjm947373
2017-08-29 11:05:12 +08:00
…… where status in (1,2,3) and is_onsale in (1,-1)……
silenceeeee
2017-08-29 11:55:10 +08:00
@zjm947373 可能我没有描述清楚,我的意思是 status 的值可能是 1 或者 2 或者 3,但是查询的时候是查的一个明确的条件,比如 status=1,或者 status=2
cye3s
2017-08-29 12:05:34 +08:00
mysql 有 bitmap 索引么?
zjm947373
2017-08-29 12:10:22 +08:00
@silenceeeee 这个不就是 in 的作用么。。。至于查询条件不是应该由你的程序来生成的么,要查 1 或 2 生成的自然就是 in (1,2)了。(或者我真没看懂你到底是在问什么)
silenceeeee
2017-08-29 13:44:39 +08:00
@zjm947373
查询条件:WHERE status=xxx (查询的时候没有使用 OR 和 IN 的需求)我称之为“但是查询的时候是查的一个明确的条件 比如 status=1,或者 status=2 ”
status 的值可能是 1 或者 2 或者 3:
status 的值可以(且只能)是 1, 2, 3 的其中一项。
finull
2017-08-29 14:08:39 +08:00
@cye3s mysql 没有 bitmap index
@silenceeeee 这个只能对这些列索引了
fcka
2017-08-29 14:20:03 +08:00
这个表有多少万行?
silenceeeee
2017-08-29 14:42:12 +08:00
@fcka 倒不是真的遇到这个问题了,就是来讨论讨论。
@finull 好吧。
kkeiko
2017-08-29 14:57:51 +08:00
mysql 的组成中有一部分叫‘查询优化器’,类似编译优化,就是你输入的语句其实不一定是最终执行的语句,mysql 自己会进行优化。你的这个问题就直接该怎么写就怎么写呗,where ... and ... and ... 只要每列都建索引了,这么写就是最优方案了。
floraX
2017-08-29 15:00:28 +08:00
@kkeiko 只要每列都建索引了,这么写就是最优方案了。
不是的
and and and,最终 用到的,仅仅是一个索引,如果可以,弄联合索引,效率高很多。。
kkeiko
2017-08-29 15:04:21 +08:00
@floraX 可能是我表达问题,我的意思是说该查的列都建上索引就行了,当然具体你 where 一个条件可以建单列索引,多个条件可以建联合索引。核心观点是得有索引
badttt
2017-08-29 18:37:06 +08:00
按照问题中的查询,只要建了索引就是最大优化,建议了解下 MySQL 中的索引最左前缀匹配
340244120
2017-08-29 19:30:39 +08:00
一个字段建好索引后,接着又在另一个联合索引中作为最左的字段。或者这两步顺序反过来。这两种情况下字段会建立两次索引吗
wintercoder
2017-08-29 21:08:00 +08:00
借楼问,类似的,上面的 status 如果为 1 的值很多,为 2 的很少,为 3 的一般多,limit 20 去查 status=1 的话很快,查 2 很慢,除了索引 还有其他方案么,加索引的话跟已有一起拼成复合的还是单独建好
wintercoder
2017-08-29 22:02:36 +08:00
@wintercoder #16 额我这种情况区分度不高,建索引也没意义,还是会走全表- -
zhx1991
2017-08-29 22:43:51 +08:00
这种区分度不高的没什么办法, 怎么捣鼓都是全表扫描

只能从别的角度下手, 比如事先算好数扔在缓存里
akira
2017-08-30 00:09:33 +08:00
没有太好的办法优化的。
最好是另外有一个字段可以上索引 并大幅减少数据。 例如时间维度?
msg7086
2017-08-30 00:58:56 +08:00
recommand

重新发号施令。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/386526

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX