这一条SQL怎么优化
SQL code
select * from dx_gd_goods where g_label >= 100101000 and g_label<100102000 order by g_likenum DESC limit 30
上面的SQL语句执行要2秒。太慢了。
我如果变成这样,但是实际需求是一定要排序的。
SQL code
select * from dx_gd_goods where g_label >= 100101000 and g_label<100102000 limit 30
这样做后,程序只需要0.16秒就可以返回
我怎样做才能到排序后,执行的时间又短呢。
------解决方案--------------------g_label 和 g_likenum 字段都建立索引没有
------解决方案--------------------我觉得你的测试不准确,没理由相差这么大。你是多次运行过取平均值吗?
------解决方案--------------------g_likenum 没有用到索引
------解决方案--------------------前一个语句执行慢,后一个执行快,我猜测原因是这样的:后者在扫描数据记录的时候,找到符合 where 条件的记录,只要凑够 30 个就好了,即使 g_label 没有索引,只要符合条件的记录在总的数据集合里所占的比例不是特别低,也没有什么问题;而前者则不行,它必须找到符合 where 条件的所有记录,然后再按照 g_likenum 排序,才能取出前面的 30 个,这个过程如果没有适当索引的帮助,很可能导致全表扫描。
解决问题的办法当然也只能是设置适当的索引。但是什么样的索引是适当的,还跟你的 dx_gd_goods 表中的数据分布特点有关系。比如,当符合 where 条件的记录所占的比例足够高,而 g_likenum 字段的区分度也很高的情况下,(g_likenum) 这样的索引就已经很好了;但如果符合 where 条件的记录只是相对很少一部分,那么 (g_label, g_likenum) 这样的索引可能效果会更好一点。
另外,有的时候数据库(比如 mysql)可能并不一定按你的想像来使用索引,所以要用 explain 进行考察,必要时可以通过 index hint 等手段进行干预。
————————————————————————————————
基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
------解决方案--------------------g_likenum 是不是数据很集中的那种?enum?
------解决方案--------------------这是前段的sql吗?如果是的话你可以给g_label 和 g_likenum建立个符合索引,你的mysql是什么版本?可以的话创建分区呢
------解决方案--------------------
------解决方案--------------------在 g_label 和 g_likenum 上建联合索引
------解决方案--------------------
------解决方案--------------------
------解决方案--------------------
------解决方案--------------------那也就只能这样了,再优化就是大动作了