【问题标题】:MySql multiple selects batching in .net.net中的MySql多选批处理
【发布时间】:2012-07-03 04:06:47
【问题描述】:

我的申请中有一个情况。对于图表中的每个 x 轴点,我正在绘制 5 个 y 轴值。要计算这 5 个值中的每一个,我需要进行 4 个不同的查询。即,对于每个 x 轴点,我需要触发 20 个 sql 查询。

现在,我需要在图表中绘制 40 个这样的点。它导致了可悲的性能,需要将近一分钟才能从数据库中取回所有数据。 4 个不同的查询中的每一个都包含 2 个表之间的连接。一个只有 6 行。另一个接近10,000。 4 个查询中的每一个都有不同的 WHERE 子句,因此它们是不同的查询。对于 x 轴上的每个点,只有 where 子句的值会发生变化。

我尝试将 4 个查询中的每一个组合成一个大字符串。基本上批量四选。这些再次针对每个 y 轴值进行批处理。 因此,对于每个 x 轴点,我现在正在触发一个包含 20 个不同选择语句的大命令。

从技术上讲,我的性能应该得到很大提升,对吧?而不是击中 db 40x5x4 = 800 次,我现在只击中了 40 次。但不是需要 60 秒,而是需要 50-55 秒……帮助不大。

我正在使用 MySql 5.1 及其 .Net 连接器的 6.1 版本。

我可以做些什么来提高性能?

编辑:

4 个查询之一如下:

SELECT
  SUM(TIME_TO_SEC(TIMEDIFF(T1.col2, T1.col1))* T2.col1 / (3600 *1000)) AS TotalTime
FROM Table T1
  JOIN Table T2 
  ON T1.col3 = T2.col3
WHERE T1.col4 = 'i'
    AND T1.col1 >= '2009-12-25 00:00:00'
    AND T1.col2 <= '2009-12-26 00:00:00';

其他 3 个查询类似,只是 where 子句略有变化。这组 4 个查询被触发 5 次。前 3 次针对表 T1 和 T2 的连接,为 col4 传递不同的值。接下来两次针对表 T3 和 T2 的连接,为 col4 传递不同的值。这 5 个值是特定 x 轴点的 y 轴值。

所有这些查询返回的数据格式相同。因此,我们尝试对所有这些查询执行 UNION ALL。没有本质区别。然而,一件奇怪的事情是,在对表 T1 的外键进行索引后[虽然它包含十万多条记录],查询正在使用该索引,但它们变得更慢了。有时,查询需要双倍的时间来返回数据。

【问题讨论】:

  • 您确定瓶颈在于创建连接和通过网络获取数据吗?也许查询本身需要时间,您需要优化它们?
  • @Oded,我认为我们通过将查询合并为一个,消除了创建连接/获取数据的瓶颈。所以是的,查询本身需要时间,我正在寻求有关如何优化它们的帮助:)

标签: .net mysql optimization query-optimization


【解决方案1】:

您消除了数据库连接问题。

所以问题一定在于查询本身需要一些时间。

对于这么小的表,您的连接应该非常快,除非您在 10K 记录中的外键没有索引。 如果不是,将其编入索引应该会显着提升。

此外,您的 800 个查询很可能可以合并为一个。您也应该获得成功(即使您添加了一些额外的连接)。

我正在考虑类似的事情

SELECT
  a.*,
  b1.needed_value,
  b2.needed_value,
  b3.needed_value,
  b4.needed_value,
  b5.needed_value
FROM
  table1 a,
  table2 b1,
  table2 b2,
  table2 b3,
  table2 b4,
  table2 b5
WHERE
  a.a_key = b1.b_key AND
  a.a_key = b2.b_key AND
  a.a_key = b3.b_key AND
  a.a_key = b4.b_key AND
  a.a_key = b5.b_key AND
  a.x_id IN (x1, x2, ...., x40)

【讨论】:

  • 我已经编辑了我的问题以包含我们正在执行的查询的示例。我在包含很多行的表上索引了外键。当它只有大约 10k 时,查询花费的时间更短。但是当该表中的数据增加到大约 20 万行时,与没有索引的情况相比,查询花费的时间增加了一倍。索引是否有可能减慢查询速度?
  • 好的,所以连接不再是瓶颈。你有 col4 的索引吗?
  • 是的,我确实有 col4 的索引。但是, col4 将仅包含 2 个值。 “我”或“一个”。我不确定索引是否会有所作为。因此,值“a”和“i”的行数几乎相等。
【解决方案2】:

如果没有看到您正在运行的查询的一些示例,就很难提出好的建议。我的第一个猜测是尝试使用 UNION 将具有相同结果结构的多个不同查询组合成一个查询,该查询只访问数据库一次。

但我认为您所描述的是您具有值依赖性,因此在您获得先前查询的值之前,您无法运行其他查询。您可以通过使用“派生表”来解决这个问题,它实际上只是一个充当表的 SELECT。

SELECT yaxis.*,xaxis.xval FROM yaxis JOIN (
SELECT xaxis.xval FROM xaxis WHERE xval IN (4, 23, 32, 75, 78) AND group_id=121
) AS xaxis ON yaxis.xval=xaxis.xval

基本上,将 SELECT 放在括号中并为其指定名称,您可以将其视为数据库表。

【讨论】:

  • 感谢您的建议。我们尝试了联合的方法,但它并没有帮助减少时间。并且查询是独立的。不依赖于前一个查询的值。
【解决方案3】:

我们发现使用 MSSQL Server 在同一个数据库上执行完全相同的查询可以提供出色的性能。阅读更多内容,我们发现很多人抱怨 MySQL 在 Windows 上的性能不佳。

我的问题是我可以做些什么来提高查询的性能。我们最终选择的答案是迁移到 MSSQL Server。

【讨论】:

    猜你喜欢
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-15
    • 2011-03-26
    • 2017-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多