我需要针对MySQL数据库从.net服务运行选择SQL查询。 该查询大约需要1秒钟才能完成,需要连续执行36次,每次运行的日期不同。
简单的查询示例,其中每次执行的日期都会更改:
SELECT * FROM person where date < "some date"
我想知道我运行查询的选项是什么,明智的选择是什么? 我应该对数据库运行36次吗? 使用存储过程并循环浏览不同的日期? 还有其他选择吗?
请注意,没有选项可以更改查询以减少执行次数,我必须运行36次,并且我试图找出每个选项的可行选项和优点和缺点。
我将尝试使查询示例更清晰:
查询由几个选择语句组成,每个选择语句都在进行计算:求和或计数出现次数等。每个查询都取决于传递给查询的日期。我需要在36个不同时间段内进行这些计算的结果。
下面的示例不是原始查询,而是其中的一部分,只是对表名等进行了一些更改。.只是为了展示总体思路。
我目前从.Net服务器对我的MYSQL DB运行查询36次。只是感觉这不是执行此操作的最佳方法。我可以考虑将查询移至存储过程,并可能在循环中运行36次相同的查询,而不是为每个查询调用DB。我想知道是否有人有更好的主意来解决多次运行具有不同参数的相同查询的问题。
示例:
SET @id = 11111;
SET @calculations_date = "2019-05-05";
SET @calculations_date_minus_1_year = DATE_SUB(@calculations_date, INTERVAL 1 YEAR);
SELECT customers.id,
IFNULL( (SELECT COUNT(DISTINCT id) FROM customer_data WHERE id = @id AND customer_data.date >= DATE_SUB(@calculations_date, INTERVAL 2 YEAR) AND customer_data.date <= @calculations_date) , 0) as customers_in_last_24_months,
IFNULL( (SELECT SUM(amount) FROM other_customer_data WHERE id = @id AND date <= @calculations_date_minus_1_year), 0) AS total_other_customer_data_until_12_months_before_date,
IFNULL( (SELECT SUM(amount) FROM other_customer_data2 WHERE id = @id AND date <= @calculations_date_minus_1_year), 0) AS total_other_customer_data2_until_12_months_before_date,
IFNULL( (SELECT SUM(amount) FROM other_customer_data3 WHERE id = @id AND date <= @calculations_date_minus_1_year), 0) AS total_other_customer_data3_until_12_months_before_date,
FROM customers
WHERE customers.id = @id;
谢谢!
答案 0 :(得分:1)
好吧,提高选择语句性能的第一个下意识的反应是在表中引入一个索引(在您的情况下为date列)。 优点:快速,简单 缺点:需要更多的磁盘空间(取决于索引的类型和表大小,这可能是可观的)
我想到的另一个选择是将整个表加载到内存中并在其中进行过滤。这肯定会更快,但是特别是对于通常不可行的大表,因为您可能会用完RAM。
如果有任何方法可以重写查询,则可能要一次为所有36个人选择,但是您说“没有选项可以更改查询” ...所以我想这个选项已经解决了窗户?
您也可以尝试使用实例化视图,但是我对MySql知之甚少,因此无法判断在您的情况下是否有意义。
希望我能够为您提供一些可以用作起点的选项;)
答案 1 :(得分:0)
如果“某个日期”之前有一百万行,那么将需要很长时间才能运行,并且您的客户端会阻塞大量数据。因此,我声称这不是一个现实的查询。
另一方面,
SELECT * FROM person where date < "some date"
ORDER BY date LIMIT 10
仅(最多)返回10行。如果存在INDEX(date)
,则查询的性能将非常快并且几乎恒定。我希望毫秒,而不是1秒。
以这种速度,您可以让360个用户“同时”进行查询。
或者您是说一个连接正在执行36 SELECTs
。在这种情况下,他们似乎将获得重叠的信息?
对于简单查询而言,开销非常大。也许我们可以将这36个查询合而为一?
此外,您是否需要表中的所有列?省略不必要的列以减少传输的体积。
答案 2 :(得分:0)
我决定在服务器端动态创建查询,并在每个部分之间包括UNION ALL,以避免多次访问数据库。