那么挑战来了,这条 sql 还能有更优化性能的写法吗?

2016-06-15 17:04:10 +08:00
 teemoer

http://ww3.sinaimg.cn/large/e38a7f8bgw1f4w0tyljcuj20kt0k1juw.jpg

SELECT m.id, m.name, mc_diag.count_size AS mc_diag_count, mc_thers.count_size AS mc_thers_count, mc_me.count_size AS mc_me_count FROM medicine m LEFT JOIN medicine_count mc_diag ON mc_diag.medicine_id = m.id AND mc_diag.doctor_id = 47 AND mc_diag.diagosis_name = '急性上呼吸道感染' LEFT JOIN medicine_count mc_me ON mc_me.medicine_id = m.id AND mc_me.doctor_id = 47 LEFT JOIN medicine_count mc_thers ON mc_thers.medicine_id = m.id AND mc_thers.doctor_id <> 47 WHERE (m.name LIKE '%w%' OR m.help_code LIKE '%w%') AND m.type = 0 GROUP BY m.name ORDER BY mc_diag_count DESC, mc_me_count DESC, mc_thers_count DESC, m.id DESC LIMIT 0, 10;

########################################## 鄙人的智商也就这么多了,诸位 SQL 大神多多指教

6421 次点击
所在节点    MySQL
69 条回复
teemoer
2016-06-16 13:37:16 +08:00
@DRcoding @.@..... 已经考虑抛弃这条 SQL 修改表结构了 这条 sql 没多大 优化的可能性
teemoer
2016-06-16 13:39:01 +08:00
@halden left join A left join B A 和 B 自己的 and 条件不一样 , 后面我排序需要用到 order by A 然后再 order by B 这个 and 是属于在 A 和 B 的 不是 属于 整条 sql 的 where 的 = = !
sampeng
2016-06-16 17:35:18 +08:00
@teemoer 那你管他干嘛。。自己折腾自己。。。
sampeng
2016-06-16 17:36:39 +08:00
另外,你自己电脑 27ms 。服务器 1s 多了。。这本身是个问题。
数据量一样?如果一样。。。这 1s 花了你得知道。
teemoer
2016-06-16 18:11:35 +08:00
@sampeng 我电脑配置 :


服务器配置 :
lecher
2016-06-16 20:53:25 +08:00
别删表字段,这种历史遗留问题的事情,原开发组成员不在的情况下,重构的试错成本是非常高的。

如果是要优化查询速度,逻辑写到代码里面,尽量做到一条 SQL 一个单表查询,中间计算结果要么用缓存 Redis memcached 之类的保存,要么再开汇总表,只要查询能利用到索引和缓存,一个请求过来拆成几十个 SQL 的速度也可以优化到一两秒之内完成。

另外就是有的统计可以在写入的时候就计算完写到汇总字段里面。

至于服务器数据处理的时间,还有很多优化的配置可以用,联表最忌讳的就是没有命中索引,一旦出现全表查询,联表的计算量是乘积提升的, A 、 B 表各一万的数据,联表没命中索引的话,计算量可是一个亿,再快的 CPU 也没必要浪费在这种无谓的联表计算上。
teemoer
2016-06-23 12:17:07 +08:00
@lecher 已经把 sql 做的事 交给 java 了 但是 性能应该还是不好, 望指点,已附加代码到 帖子
lecher
2016-06-24 05:58:13 +08:00
全取出来自己计算关系没有完全发挥数据库的性能,循环主体是求四个集合的交集。
属于某医生的药品
不属于某医生的药品
属于某疾病的药品
不属于某疾病的药品

这四个集合有没有办法通过单表查询从数据库取出来?
如果按医生为主体循环,那么是否属于某疾病的药品这两个集合可以缓存在内存中。减少很多数据库查询请求和循环处理。
预处理取出这些药品的分类集合并且按药品 ID 排序之后。
主循环的业务就可以调整成求四个集合直接的交集,这个就可以通过归并排序的思路求交集,当然 Java 内置方法也有求交际的库可以用,只要预处理好,性能应该还可以优化一下。
teemoer
2016-06-24 11:13:56 +08:00
@lecher 明白 了解了

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

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

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

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

© 2021 V2EX