更快地运行SQL查询
这绝不是一个特别复杂的查询,但由于数据库已正常化到一个良好的级别,并且我们正在处理大量数据,因此对于用户来说,此查询可能非常慢 有没有人对如何提高速度有什么建议?如果我对数据库的某些部分进行战略性的非规范化,这会有帮助吗?在存储过程中运行它会带来显著的改进吗 在我的代码中,我处理数据的方式是高效的,瓶颈实际上是这个查询更快地运行SQL查询,sql,sql-server-2000,query-optimization,normalization,relational-database,Sql,Sql Server 2000,Query Optimization,Normalization,Relational Database,这绝不是一个特别复杂的查询,但由于数据库已正常化到一个良好的级别,并且我们正在处理大量数据,因此对于用户来说,此查询可能非常慢 有没有人对如何提高速度有什么建议?如果我对数据库的某些部分进行战略性的非规范化,这会有帮助吗?在存储过程中运行它会带来显著的改进吗 在我的代码中,我处理数据的方式是高效的,瓶颈实际上是这个查询 谢谢 我会尝试打破这种局面 SELECT projectID, urlID, COUNT(1) AS totalClicks, projectPage, (SELEC
谢谢 我会尝试打破这种局面
SELECT projectID, urlID, COUNT(1) AS totalClicks, projectPage,
(SELECT COUNT(1)
FROM tblStatSessionRoutes, tblStatSessions
WHERE tblStatSessionRoutes.statSessionID = tblStatSessions.ID
AND tblStatSessions.projectID = tblAdClicks.projectID
AND (tblStatSessionRoutes.leftPageID = tblAdClicks.projectPage OR
tblStatSessionRoutes.rightPageID = tblAdClicks.projectPage)) AS totalViews
FROM tblAdClicks
WHERE projectID IN (SELECT projectID FROM tblProjects WHERE userID = 5)
GROUP BY projectID, urlID, projectPage
ORDER BY CASE projectID
WHEN 170 THEN
1
ELSE
0
END, projectID
并改为使用联接:
projectID IN (SELECT projectID FROM tblProjects WHERE userID = 5)
不知道这会有多大帮助-我希望会有帮助
除此之外,我会检查相关列上是否有索引,例如a.ProjectID上的索引,以帮助连接,也许在a.urlID和a.ProjectPage上,通过对数据库进行反规范化是最后的手段,因为只选择一个原因,您不想鼓励数据不一致,而反规范化将允许数据不一致 第一件事是看看是否可以从查询执行计划中获得一些线索。例如,可能是您的子选择成本太高,最好先将其放入临时表中,然后将其加入到主查询中 此外,如果您看到大量的表扫描,您可以从改进的索引中获益
如果您还没有,您应该花几分钟重新格式化查询以提高可读性。令人惊讶的是,在执行此操作时,明显的优化经常会跳到您身上。如果您的dbms有一个解释其查询计划的工具,请首先使用该工具。您的第一个相关子查询可能每行运行一次。然后确保WHERE子句中引用的每一列都有索引 这个子查询,其中projectd在SELECT projectd FROM tblProjects中,其中userID=5-可以从作为视图进行剪切和实现中获益。然后加入视图 将clickstream数据视为数据仓库应用程序并不罕见。如果需要这样做,我通常会实现一个单独的数据仓库,而不是对设计良好的OLTP数据库进行反规范化
我怀疑将其作为存储过程运行是否会对您有所帮助。我会尝试删除内部SELECT COUNT1…的相关子查询。。。。如果必须加入到左侧页面或右侧页面匹配的会话路由中,则会使事情变得有点棘手。类似的东西,但我还没有测试过:
SELECT
projectID, urlID, COUNT(1) AS totalClicks, projectPage,
(SELECT COUNT(1) ....) AS totalViews
FROM
dbo.tblAdClicks a
INNER JOIN
dbo.tblProjects p ON a.ProjectID = p.ProjectID
WHERE
p.UserID = 5
GROUP BY
a.projectID, a.urlID, a.projectPage
ORDER BY
CASE a.projectID
WHEN 170 THEN 1
ELSE 0
END, a.projectID
如果我要添加一些缓存表来帮助实现这一点,正如我所指出的,我会尝试将针对tblStatSessionRoutes的两个查询(左页和右页)减少为一个查询。如果您知道leftPageID永远不会等于rightPageID,则可以简单地使用触发器在单独的行中用左视图和右视图填充其他表。您使用的是什么RDBMS?MySQL、SQL Server、Postgres?SQL Server就是在上面运行的。只有v2000,这有点垃圾!此外,查询中的某些格式也不会出错。编辑:哦,那更好。有两个主要问题1数据库没有正常化,但你认为它是正常的。对未规范化的数据进行非规范化可能会有所帮助,但对其进行规范化则会有更大帮助。在数据模型中发布一个新问题。2查询格式不正确,外部查询没有定义子查询可以依赖的清晰结构。当然,IN使用了一个工作表,所以把它改成join,+1表示我要说的一切。将其链接到查询分析器并查看执行计划。
SELECT tblAdClicks.projectID, tblAdClicks.urlID, COUNT(1) AS totalClicks, tblAdClicks.projectPage,
SUM(CASE WHEN leftRoute.statSessionID IS NOT NULL OR rightRoute.statSessionID IS NOT NULL THEN 1 ELSE 0 END) AS totalViews
FROM tblAdClicks
JOIN tblProjects ON tblProjects.projectID = tblAdClicks.projectID
LEFT JOIN tblStatSessions ON tblStatSessions.projectID = tblAdClicks.projectID
LEFT JOIN tblStatSessionRoutes leftRoute ON leftRoute.statSessionID = tblStatSessions.ID AND leftRoute.leftPageID = tblAdClicks.projectPage
LEFT JOIN tblStatSessionRoutes rightRoute ON rightRoute.statSessionID = tblStatSessions.ID AND rightRoute.rightPageID = tblAdClicks.projectPage
WHERE tblProjects.userID = 5
GROUP BY tblAdClicks.projectID, tblAdClicks.urlID, tblAdClicks.projectPage
ORDER BY CASE tblAdClicks.projectID WHEN 170 THEN 1 ELSE 0 END, tblAdClicks.projectID