[英]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.