MySQL数据子集上的查询性能



我建立了一个收集和分析调查的小系统,我需要找到优化性能的方法。我注意到许多查询都有共同的部分,它们被执行了很多次。在下面的示例中,survey_q_id ' = '180002'部分是更改的部分。

SELECT COUNT(`result_q`.`id`) as result_q_c 
FROM result_q
LEFT JOIN `survey_save` ON `survey_save`.`id` = `result_q`.`ss_id` 
WHERE `result_q`.`survey_q_id` = '180002' 
AND `survey_save`.`survey_order_id` IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 
AND `survey_save`.`id` IN (7,9,24,26,29,30,31,33,34,38,39,41,45,46,47,50,51,52,53,64,65,68,74,76,79,81,82,87,92,93,96,115,116,117,131,148,149,150,151,153,155,156,159,160,162,165,166,168,176,179,182,186,188,190,194,201,204,208,210,211,216,221,226,235,236,232,250,266,279,280,283,287,290,298,299,304,307,308,315,317,318,330,342,356,357,358,360,366,367,370,373,374,379,380,383,390,391,394,397,402,404,405,406,408,413,415,436,446,450,458,465,467,468,469,471,473,477,479,480,481,485,489,493,494,500,504,518,521,532,536,539,542,544,568,570,574,576,579,582,584,585,586,594,595,598,621,622,629,651,652,653,657,658,665,669,674,675,684,690,696,700,708,712,715,721,722,723,724,739,740,749,756,757,761,764,765,767,770,775,776,780,787,788,792,800,805,809,813,815,818,821,824,829,830,831,832,841,843,865,866,867,868,869,870,871,872,873,874,875,876,877,878,879,880,881,882,883,884,885,886,887,888,889,890,891,892,893,894,895,896,982,983,986,988,991,993,996,998,1001,1003,1006,1009,1011,1013,1019,1021,1024,1027,1032,1061) 
AND `result_q_radio`.`date_save` > '2019-01-01 00:00:00'
AND `result_q_radio`.`date_save` < '2022-05-16 12:19:44'

所以数据集是有限的,然后我需要计算部分数据集中有多少列集合的id为x。对survey_order_id和所有id进行索引。数据集不是静态的——result_q表每天增长很多,但是当执行分析时,result_q条目的范围是只读的,因此当允许分析时,不会向分析的数据集添加新元素。因此,由Y人填写的调查X在result_q表中生成了许多条目,但是当调查关闭时,这些条目不会改变-添加了新条目,但由该调查组成的集合不会改变。

收集的数据量每天都在增长,我需要能够告诉MySQL,我们只对每个请求处理这些行。数据将以多种方式进行分析,因此这些将不是静态的,而是在特定页面上调用,许多查询的大部分将只对数据的特定部分起作用。我假设有一些缓存机制可以在后台优化这个,但如果有人有任何改进的想法,我将不胜感激。

可能是一些额外的调用或以某种方式准备数据集之前或某种手动缓存,将临时收集要处理的数据,所以只有那位被分析?

谢谢!

p。当前工作版本:PHP7.4 + 10.3.27-MariaDB

谢谢大家!@Chris Haas虽然查询中使用的所有INT列都被索引了,但还有其他查询也在result_q_radio表中询问INT并且没有被索引。我实际上已经实现了一个缓存表,它已经削减了之前已经执行过的查询,并且已经完成的查询的性能快了5倍,但是当用户点击过滤结果时,问题仍然存在,这必须重新计算另一个调查结果的组合。我想,由于数据在调查收集完成后是只读的,所以我将制作一个队列系统来缓存大多数通常的组合,并在每天晚上执行CRON来准备缓存,这样就不会对性能产生大的负载。我也诊断了我的PHP本身,但虽然我不能说它是完美的,但它似乎不是一个问题,当数据库中的记录数量增长时,应该呈指数级下降。
我还急切地咨询了客户和托管公司,如果从共享主机切换到专用服务器,是否可以提高性能,至少可以给我们时间进行优化。

但是经过大量的压力,我访问了phpmyadmin和结果表,并注意到它有一些INT列在查询的其他地方使用,并且很少点击我索引了它们。速度的提高是天文数字! 总而言之就是对所有INT类型表中的所有列建立索引并用于查询的地方。所以Chris Haas-谢谢你-你的第一个回复,虽然我一开始忽略了(嘿,我已经索引了!)最后证明是最准确的-我没有检查其他表和其他查询,只关注那些在这个直接查询中,我怀疑是最慢的。O也提出了同样的解决方案。琼斯-谢谢!

感谢Christoffer, The Impaler, KIKO Software, O. Jones和Rick James !

  1. 准备好的语句听起来不值得KIKO的描述
  2. 我不认为沉默转换到内部连接是一个可行的问题来源,因为这很可能在SQL中以某种方式内部缓存,但将来我会考虑这个解决方案以及一个额外的优化方法。Rick James发现了错字——result_q应该是result_q_radio在代码的任何地方——我只在开头把它改成了q,而忘记了剩下的那些。每个问题类型都有单独的表-无线电,检查,矩阵无线电等,我不想引起注意为什么它是无线电在问题中,因为所有的表工作相似。

谢谢大家,祝你们今天愉快!

最新更新