2

在查看过去几天时,我正在编写的查询运行良好,一旦我经过一个多星期,它就会爬行(约 20 分钟)。我将 3 张桌子连接在一起。我想知道我应该寻找什么东西来让它运行得更快。我真的不知道该帖子还需要哪些其他信息。

编辑:更多信息:db 是 Sybase 10。查询:

SELECT a.id, a.date, a.time, a.signal, a.noise,
b.signal_strength, b.base_id, b.firmware,
a.site, b.active, a.table_key_id
FROM adminuser.station AS a
JOIN adminuser.base AS b
ON a.id = b.base_id
WHERE a.site = 1234 AND a.date >= '2009-03-20'

我还取出了 3rd JOIN,它仍然运行得非常慢。我应该尝试另一种 JOIN 方法吗?

4

8 回答 8

2

通过在 SQL Server Management Studio 中运行查询并设置包括实际执行计划选项(在查询菜单中) ,您可以获得大量信息(假设您在此处使用 MSSQL )。

这将向您显示 SQLServer 为执行查询而执行的步骤图 - 每个步骤的相对成本。

下一步是稍微修改查询(尝试以不同的方式进行),然后同时运行新版本和旧版本。您将获得两个执行计划,其相对成本不仅针对每个步骤,而且针对查询的两个版本!因此,您可以客观地判断您是否正在取得进展。

我在调试/优化查询时一直这样做。

于 2009-03-31T03:16:14.707 回答
2

我不太了解 Sybase 10,但尝试运行该查询 10 天,然后在一段时间内的每一天分别运行 10 次并比较时间。如果第一种情况下的时间要长得多,那么您可能已经达到了数据库缓存限制。

解决方案不是简单地在循环中运行较短时间的查询(在程序中,而不是 SQL)。如果表 A 按日期分区,则效果特别好。

于 2009-03-31T13:20:05.877 回答
1

确保您在外键上有索引。

于 2009-03-31T03:45:37.943 回答
0

这听起来更像是您有内存泄漏或没有在您的客户端代码中关闭数据库连接,而不是查询有任何问题。

[编辑]
没关系:您的意思是查询日期范围而不是服务器处于活动状态的持续时间。我会留下这个来帮助其他人避免同样的困惑。

此外,如果您可以发布 sql 查询,即使您需要先对其进行一些混淆,也会有所帮助,并且最好检查您的日期列上是否有索引以及较长范围返回的记录数。

于 2009-03-31T03:05:27.353 回答
0

如果您的数据库支持,您可能需要考虑使用 PARTITION 作为日期范围。我听说这有很大帮助。

于 2009-03-31T03:11:44.530 回答
0

抓住这本书“Professional SQL Server 2005 Performance Tuning”,它非常棒。

于 2009-03-31T03:59:07.193 回答
0

你没有提到你的数据库。如果不是 SQL Server,如何获取数据的细节可能会有所不同,但建议基本相同。

看看索引,当然,但首先要做的是遵循 Blorgbeard 的建议并使用 Management Studio 扫描执行计划(同样,如果您正在运行 SQL Server)。

我猜你会看到,对于小的日期范围,优化器会选择一个合理的查询计划,但是当日期范围很大时,它会选择完全不同的东西,可能涉及表扫描或索引扫描,并且可能导致非常大的临时记录集的连接。执行计划分析器将揭示所有这些。

扫描意味着优化器认为对整个表或整个索引进行打磨比寻找特定值更便宜。

您最终想要做的是获取索引和查询的语法设置,以便您在查询的查询计划中保留索引搜索,无论日期范围如何,或者,如果失败,您需要的扫描也会被过滤因为您可以设法最小化临时记录集的大小,从而避免过多的读取和 I/O。

于 2009-03-31T12:40:47.280 回答
0
SELECT

 a.id, a.date, a.time, a.signal, a.noise,a.site, b.active, a.table_key_id,
 b.signal_strength, b.base_id, b.firmware

FROM 

( SELECT * FROM adminuser.station 
      WHERE site = 1234 AND date >= '2009-03-20') AS a
JOIN 

    adminuser.base AS b
ON

    a.id = b.base_id

有点重写查询,以便首先过滤所需的行然后执行连接,而不是执行连接然后过滤结果。

而不是从子查询中提取 * 您可以只选择您想要的列,这可能没什么帮助。

可能这对加速事情没有什么帮助。

虽然这在 MySql 中有效,但我不确定 sysbase 语法。

于 2009-03-31T21:52:07.923 回答