現狀:
我有6000名學生上線的站點數據庫,並在試驗現場,有400測試學生的數據庫。使用搜索功能搜索學生(下圖)在測試網站上工作正常,但在現場網站上搜索功能需要1-2分鐘的時間才能返回(甚至需要通過執行RequestTimeout = 180來增加腳本超時)。這兩個網站使用相同的搜索功能(如下)。這個coldfusion9 SQL搜索查詢可以更快嗎?
問題:
我的問題是做任何你有關於如何使搜索更快了什麼祕訣?它太慢了。
搜索功能:
<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
'DISTINCT'和'LIKE'是兩個可以執行較慢的操作。你的查詢計劃是什麼樣的?任何索引?另外,返回第一個查詢中的所有列,僅僅是爲了獲得行計數效率低下。你可以考慮使用'SQL_CALC_FOUND_ROWS' /'FOUND_ROWS()'來估計找到的總行數。至少,嘗試將第一個查詢轉換爲某種「COUNT(..)」http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows – Leigh
確實(重新這兩個查詢)。就目前而言,您可能只需在ColdFusion中運行一個查詢和分頁即可 - 儘管只運行count()可能更可取。 –