我有一个课程搜索引擎,当我尝试进行搜索时,显示搜索结果需要很长时间。您可以尝试在这里进行搜索
http://76.12.87.164/cpd/testperformance.cfm
在该页面上,您还可以看到数据库表和索引(如果有)。
我没有使用存储过程 - 查询是使用 Coldfusion 内联的。
我想我需要创建一些索引,但我不确定是哪种(集群、非集群)以及在哪些列上。
谢谢
我有一个课程搜索引擎,当我尝试进行搜索时,显示搜索结果需要很长时间。您可以尝试在这里进行搜索
http://76.12.87.164/cpd/testperformance.cfm
在该页面上,您还可以看到数据库表和索引(如果有)。
我没有使用存储过程 - 查询是使用 Coldfusion 内联的。
我想我需要创建一些索引,但我不确定是哪种(集群、非集群)以及在哪些列上。
谢谢
您需要在WHERE
子句中出现的列上创建索引。该规则有几个例外:
x LIKE '%something'
那么索引没有意义。如果您将索引视为指定行的特定顺序x
,那么如果您正在搜索“%something” ,则按排序是没有用的:无论如何您都必须扫描所有行。因此,让我们看一下您正在搜索“关键字'会计'”的情况。根据您的结果页面,生成的 SQL 是:
SELECT
*
FROM (
SELECT TOP 10
ROW_NUMBER() OVER (ORDER BY sq.name) AS Row,
sq.*
FROM (
SELECT
c.*,
p.providername,
p.school,
p.website,
p.type
FROM
cpd_COURSES c, cpd_PROVIDERS p
WHERE
c.providerid = p.providerid AND
c.activatedYN = 'Y' AND
(
c.name like '%accounting%' OR
c.title like '%accounting%' OR
c.keywords like '%accounting%'
)
) sq
) AS temp
WHERE
Row >= 1 AND Row <= 10
在这种情况下,我将假设它cpd_COURSES.providerid
是一个外键,cpd_PROVIDERS.providerid
在这种情况下您不需要索引,因为它已经有一个。
此外,该activatedYN
列是 T/F 列,并且(根据我上面关于将可能值限制为仅 50% 的规则)T/F 列也不应该被索引。
最后,因为使用x LIKE '%accounting%'
查询进行搜索,您也不需要名称、标题或关键字的索引——因为它永远不会被使用。
所以在这种情况下你需要做的主要事情是确保它cpd_COURSES.providerid
实际上是cpd_PROVIDERS.providerid
.
因为您使用的是 SQL Server,所以 Management Studio 有许多工具可以帮助您决定需要在哪里放置索引。如果您使用“索引调整向导”,它实际上通常很擅长告诉您什么会给您带来良好的性能改进。您只需将查询剪切并粘贴到其中,它就会返回有关要添加的索引的建议。
你仍然需要对你添加的索引有点小心,因为你拥有的索引越多,INSERT
s 和UPDATE
s 就会越慢。因此,有时您需要整合索引,或者如果它们不能提供足够的性能优势,则完全忽略它们。需要一些判断。
这是真实的实时数据库数据吗?52,000 条记录是一个很小的表,相对而言,SQL 2005 可以处理。
我想知道为 SQL 服务器分配了多少 RAM,或者数据库位于哪种磁盘上。IDE 甚至 SATA 硬盘无法提供与 15K RPM SAS 磁盘相同的性能,如果有足够的 RAM 来缓存大量经常访问的数据,那就太好了。
说了这么多,我觉得“ (c.name like '%accounting%' OR c.title like '%accounting%' OR c.keywords like '%accounting%') ”子句是有问题的。
您能否创建一个单独的 Course_Keywords 表,其中包含“courseid”和“keyword”两列(varchar(24) 对于最长的关键字就足够了?),在 courseid+keyword 上有一个复合聚集索引
然后,为了使 UI 更加友好,当人们在关键字输入字段中键入单词时,使用 AJAX 应用关键字验证和自动完成。这为您提供了具有精确关键字搜索的幕后优势,无需使用 LIKE 运算符进行模式匹配......
我会尝试将您的 IN 语句更改为 EXISTS 查询,以查看您是否在邮政编码查找中获得更好的性能。我的经验是 IN 语句适用于小型列表,但它们越大,您可以从 EXISTS 中获得更好的性能,因为查询引擎将停止搜索它遇到的第一个实例的特定值。
<CFIF zipcodes is not "">
EXISTS (
SELECT zipcode
FROM cpd_CODES_ZIPCODES
WHERE zipcode = p.zipcode
AND 3963 * (ACOS((SIN(#getzipcodeinfo.latitude#/57.2958) * SIN(latitude/57.2958)) +
(COS(#getzipcodeinfo.latitude#/57.2958) * COS(latitude/57.2958) *
COS(longitude/57.2958 - #getzipcodeinfo.longitude#/57.2958)))) <= #radius#
)
</CFIF>
您需要在搜索的字段上创建索引。索引是由索引字段预先排序的记录的二级列表。
想想老式的印刷黄页——如果你想按姓氏查找一个人,电话簿已经按这种方式排序——姓氏是聚集索引字段。如果您想查找名为 Jennifer 的人或电话号码为 867-5309 的人的电话号码,则必须搜索每个条目,并且需要很长时间。如果后面有一个索引,将所有电话号码或名字与电话簿中列出此人的页面一起按顺序列出,那会快很多。这些将是非聚集索引。
使用CF9?尝试使用 Solr 全文搜索而不是%xxx%
?