需要帮助优化 ColdFusion 查询从多个表中提取数据
我编写了一个查询,我的数据库管理员告诉我需要优化,但我的 SQL 知识有限。该查询会提取新闻稿以及每份新闻稿的 1 张相关照片和标题。它根据 id 连接站点(位置)表。
<cfquery name="local.query" datasource="#this.Dsn()#">
SELECT
pr.press_release_id,
pr.Site_id,
pr.press_release_subject,
pr.press_release_title,
pr.press_release_datetime,
pr.press_release_number,
pr.press_release_published_flag,
pr.press_release_top_story,
pr.related_photo_gallery,
pr.related_page,
s.site_name,
(SELECT TOP 1 ph.press_release_photo_lowres_filename
FROM
tbl_photo as ph
WHERE
ph.press_release_id = pr.press_release_id) as photo_filename,
(SELECT TOP 1 ph.press_release_photo_caption
FROM
tbl_photo as ph
WHERE
ph.press_release_id = pr.press_release_id) as photo_caption
FROM
tbl_press_release as pr
INNER JOIN tbl_site s
ON pr.Site_id = s.site_id
WHERE
LEFT(pr.press_release_number,1) <> <cfqueryparam cfsqltype="cf_sql_varchar" value="I">
<cfif val(event.GetValue("site_id")) gt 0>
AND s.site_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#val(event.GetValue("site_id"))#">
</cfif>
<cfif event.GetValue("pao_search") neq "">
AND
(
press_release_subject like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#event.GetValue("pao_search")#%">
OR
press_release_copy like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#event.GetValue("pao_search")#%">
OR
press_release_wingspan_title like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#event.GetValue("pao_search")#%">
OR
press_release_wingspan_subject like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#event.GetValue("pao_search")#%">
)
</cfif>
AND pr.press_release_published_flag = <cfqueryparam cfsqltype="cf_sql_integer" value="1">
AND (pr.press_release_top_story <> <cfqueryparam cfsqltype="cf_sql_bit" value="True"> OR pr.press_release_top_story IS NULL)
<cfif listLen(event.GetValue("orderBy")) neq 0>
ORDER BY
<cfloop list="#event.GetValue("orderBy")#" index="local.o">#local.o# #uCase(event.GetValue("sort"))#<cfif local.o neq listLast(event.GetValue("orderBy"))>,</cfif></cfloop>
</cfif>
</cfquery>
据管理员告诉我,嵌入的 SELECT 语句正在减慢查询速度。我现在意识到,没有必要为每个新闻稿提取相关的图像和标题,因为我只需要使用 press_release_top_story 等于 true 的新闻稿来提取它们。我认为这也可能有助于节省一些 CPU。
我可以做什么来优化这个?仅供参考,这对于 SQL Server 来说很重要。
I wrote a query that my db admins are telling me need optimized, but my SQL knowledge is limited. The query pulls the press releases and 1 related photo and caption for each. It joins the site (location) table on id.
<cfquery name="local.query" datasource="#this.Dsn()#">
SELECT
pr.press_release_id,
pr.Site_id,
pr.press_release_subject,
pr.press_release_title,
pr.press_release_datetime,
pr.press_release_number,
pr.press_release_published_flag,
pr.press_release_top_story,
pr.related_photo_gallery,
pr.related_page,
s.site_name,
(SELECT TOP 1 ph.press_release_photo_lowres_filename
FROM
tbl_photo as ph
WHERE
ph.press_release_id = pr.press_release_id) as photo_filename,
(SELECT TOP 1 ph.press_release_photo_caption
FROM
tbl_photo as ph
WHERE
ph.press_release_id = pr.press_release_id) as photo_caption
FROM
tbl_press_release as pr
INNER JOIN tbl_site s
ON pr.Site_id = s.site_id
WHERE
LEFT(pr.press_release_number,1) <> <cfqueryparam cfsqltype="cf_sql_varchar" value="I">
<cfif val(event.GetValue("site_id")) gt 0>
AND s.site_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#val(event.GetValue("site_id"))#">
</cfif>
<cfif event.GetValue("pao_search") neq "">
AND
(
press_release_subject like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#event.GetValue("pao_search")#%">
OR
press_release_copy like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#event.GetValue("pao_search")#%">
OR
press_release_wingspan_title like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#event.GetValue("pao_search")#%">
OR
press_release_wingspan_subject like <cfqueryparam cfsqltype="cf_sql_varchar" value="%#event.GetValue("pao_search")#%">
)
</cfif>
AND pr.press_release_published_flag = <cfqueryparam cfsqltype="cf_sql_integer" value="1">
AND (pr.press_release_top_story <> <cfqueryparam cfsqltype="cf_sql_bit" value="True"> OR pr.press_release_top_story IS NULL)
<cfif listLen(event.GetValue("orderBy")) neq 0>
ORDER BY
<cfloop list="#event.GetValue("orderBy")#" index="local.o">#local.o# #uCase(event.GetValue("sort"))#<cfif local.o neq listLast(event.GetValue("orderBy"))>,</cfif></cfloop>
</cfif>
</cfquery>
From what the admins told me, the embedded SELECT statements are slowing the query down. I realize now that pulling associated images and captions for every press release is unnecessary since I only need to pull them for press releases with press_release_top_story that equals true. I think that might help save some CPU as well.
What can I do to optimize this? FYI this is for SQL Server is that matters.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先也是最重要的,考虑缓存。 ColdFusion 可以轻松缓存查询(例如
...
,但是如果您需要确保 (),其中在更新新闻稿表时放入值。底层新闻稿表更新时的及时性,请改为使用
cachePut()
和cacheGet 条款LIKE 语句可能是速度变慢的罪魁祸首:需要考虑的两种方法是 SQL Server 全文索引或使用 ColdFusion的搜索功能。另外,使用SQL服务器的数据库调优顾问对查询进行查看是否有其他索引可以提高性能。
First and foremost, consider caching. ColdFusion can easily cache queries (e.g.
<cfquery cachedWithin="#createTimeSpan(d, h, m, s)#">...</cfquery>
, but if you need to ensure timeliness when the underlying press release table updates, instead usecachePut()
andcacheGet()
, where values are put in when the press release table is updated.Next, the WHERE clause LIKE statements are probably the culprit for the slowdown: two approaches to consider are a SQL Server full text index or using ColdFusion's search capabilities. In addition, use SQL Server's database tuning advisor on the query to see if there are other indices that will improve performance.
我认为 Orangepips 认为 LIKE 语句是罪魁祸首,而不是子选择可能是正确的。
作为一种快速而肮脏的方法,您可以做一件事来查看 sql server 是否可以提出改进建议,即将查询复制到 Management Studio 中,运行它以确保它有效,然后右键单击编辑器并选择“分析数据库中的查询”发动机调整顾问”。完成这个过程,它至少会找到任何明显丢失的索引。
I think orangepips is probably right regarding the LIKE statements being the culprit, and not the subselects.
One thing you can do as a quick and dirty way to see if sql server can suggest improvements, is to copy the query into management studio, run it to ensure it works, and then right click in the editor and select "Analyze query in database engine tuning advisor". Go through that process, and it'll at least find any obvious missing indexes.