[英]Can this coldfusion9 SQL search query be made faster?
情况:
我在一个现场站点上有6000名学生的数据库,而在一个测试站点上,有400名测试学生的数据库。 使用搜索功能(如下)搜索学生在测试站点上可以正常工作,但是在实时站点上,搜索功能需要1-2整分钟才能返回( 甚至需要通过执行RequestTimeout = 180来增加脚本超时 )。 两个站点使用相同的搜索功能(如下)。
问题:
我的问题是,您有没有关于如何更快地进行搜索的提示? 太慢了
搜索功能:
<cffunction name="getStudentsByKeyword" access="public" output="no" returntype="struct">
<cfargument name="keyword" type="string" required="yes">
<cfargument name="pageNum" type="numeric" default="1">
<cfargument name="startIndex" type="numeric" default="1">
<cfargument name="numItemsPerPage" type="numeric" default="20">
<cfset var resultStruct = StructNew()>
<cfset resultStruct.numAllItems=0>
<cfset resultStruct.numDisplayedItems=0>
<cfset resultStruct.courses=QueryNew("studentID")>
<cfif Arguments.pageNum GT 1>
<cfset Arguments.startIndex=(Arguments.pageNum - 1) * Arguments.numItemsPerPage + 1>
</cfif>
<cfquery name="qNumStudents" datasource="#this.datasource#">
SELECT DISTINCT COUNT(cl_student.studentID) AS numItems
FROM cl_student LEFT JOIN cl_ordersummary ON cl_student.studentID=cl_ordersummary.studentID
WHERE cl_student.email LIKE <cfqueryparam cfsqltype="cf_sql_char" value="%#Arguments.keyword#%"> OR
cl_ordersummary.contactFirstName LIKE <cfqueryparam cfsqltype="cf_sql_char" value="%#Arguments.keyword#%"> OR
cl_ordersummary.contactLastName LIKE <cfqueryparam cfsqltype="cf_sql_char" value="%#Arguments.keyword#%">
</cfquery>
<cfset resultStruct.numAllItems = qNumStudents.numItems>
<cfquery name="qStudents" datasource="#this.datasource#">
SELECT DISTINCT cl_student.studentID, cl_student.email, cl_student.password, cl_student.studentType,
cl_ordersummary.contactFirstName, cl_ordersummary.contactLastName
FROM cl_student LEFT JOIN cl_ordersummary ON cl_student.studentID=cl_ordersummary.studentID
WHERE cl_student.email LIKE <cfqueryparam cfsqltype="cf_sql_char" value="%#Arguments.keyword#%"> OR
cl_ordersummary.contactFirstName LIKE <cfqueryparam cfsqltype="cf_sql_char" value="%#Arguments.keyword#%"> OR
cl_ordersummary.contactLastName LIKE <cfqueryparam cfsqltype="cf_sql_char" value="%#Arguments.keyword#%">
ORDER BY cl_student.email, cl_ordersummary.contactFirstName, cl_ordersummary.contactLastName
LIMIT #Arguments.startIndex-1#, #Arguments.numItemsPerPage#
</cfquery>
<cfset resultStruct.numDisplayedItems=qStudents.recordcount>
<cfset resultStruct.students = qStudents>
<cfreturn resultStruct>
</cffunction>
表说明:
( 用于搜索的每个表的简单表示 )
Table cl_student
================
studentID, email, password, studentType, sendReminderEmail, firstName, middleName, lastName, address, city, state, zip, daytimePhone, dateCreated, dateLastModified
----------------
studentID INT UNSIGNED(10) (PRIMARY) (AI)
email VARCHAR(100)
password VARCHAR(20)
studentType ENUM('A','B','C','D','F')
sendRemiderEmail TINYINT(4)
firstName VARCHAR(30)
middleName VARCHAR(30)
lastName VARCHAR(30)
address VARCHAR(100)
city VARCHAR(30)
state VARCHAR(30)
zip VARCHAR(10)
daytimePhone VARCHAR(20)
dateCreated DATETIME
dateLastModified DATETIME
Table cl_ordersummary
=====================
orderID, studentID, orderDate, status, donationAmount, total, contactFirstName, contactLastName, contactAddress1, contactAddress2, contactCity, contactState, contactZIP, daytimePhone, cellPhone, billingFirstName, billingLastName, billingAddress1, billingAddress2, billingCity, billingState, billingZIP, payWithCash, authCode, remark, dateLastModified
---------------------
orderID VARCHAR(20) (PRIMARY)
studentID INT(11)
orderDate DATETIME
status CHAR(1)
donationAmount FLOAT
total FLOAT
contactFirstName VARCHAR(50)
contactLastName VARCHAR(50)
contactAddress1 VARCHAR(100)
contactAddress2 VARCHAR(100)
contactCity VARCHAR(50)
contactState VARCHAR(50)
contactZIP VARCHAR(10)
daytimePhone VARCHAR(30)
cellPhone VARCHAR(30)
billingFirstName VARCHAR(50)
billingLastName VARCHAR(50)
billingAddress1 VARCHAR(100)
billingAddress2 VARCHAR(100)
billingCity VARCHAR(50)
billingState VARCHAR(50)
billingZIP VARCHAR(10)
payWithCash TINYINT(4)
authCode VARCHAR(20)
remark TEXT
dateLastModified DATETIME
是否期望并希望您在每个学生的记录集中有多个联系人姓名? 这种设置(在订单表中有联系人姓名而不是学生表)在这种情况下似乎正在创建查询的必要性,而不是最优的。 我了解,当然有充分的理由,但值得检查。 那么,您是否想要/期望这个?
studentId|email|password|studentType|contactFirstName|contactLastName
999 b@b.b|p455w0rd|slacker |billy |bob
999 b@b.b|p455w0rd|slacker |bill |bob
...
如果是这样,则不确定第二个查询如何更快。 但是,第一个查询可能会受益于更改为以下查询,该查询将始终仅返回单行,而无需left join
或select distinct
的select distinct
:
SELECT count(s.*) as nAllResults
FROM cl_student s
WHERE s.email LIKE <cfqueryparam cfsqltype="cf_sql_char" value="%#Arguments.keyword#%">
OR EXISTS (
SELECT 1
FROM cl_ordersummary o
WHERE o.studentId = s.studentId
AND ( o.contactFirstName LIKE <cfqueryparam cfsqltype="cf_sql_char" value="%#Arguments.keyword#%">
OR o.contactLastName LIKE <cfqueryparam cfsqltype="cf_sql_char" value="%#Arguments.keyword#%"> )
)
另一件事要看的是索引。 索引不会在您的LIKE
子句中使用,但会在您的JOINS
和ORDER BY
子句中使用。 确保在表上有适当的索引,并且已定义了“ Pimary”和“ Foreign Key”。
可以使ColdFold9 SQL搜索查询更快吗?
是。 您要为受影响的列配置索引 。
Coldfusion不执行您的查询。 它被传递到您的数据库服务器以执行,然后将结果集传递回去。
您可以查询并使用查询分析器来生成执行计划,以查看查询花费最多的时间。 您很可能需要在WHERE条件中使用的列上添加一些索引。 我相信在MySQL中,您可以使用EXPLAIN向您显示缺少索引的位置http://dev.mysql.com/doc/refman/5.5/en/using-explain.html
尝试在cl_ordersummary(studentID)上创建CREATE INDEX cl_ordersummary_studentID
其他索引也可以提供帮助,但是您必须使用前缀搜索进行此优化,SQL数据库通常将前缀搜索转换为索引范围扫描。 例如,您可以索引电子邮件并将前缀用作参数:
MySQL http://dev.mysql.com/doc/refman/5.0/en/fulltext-natural-language.html (所有主要数据库都具有类似的搜索功能)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.