簡體   English   中英

可以使ColdFold9 SQL搜索查詢更快嗎?

[英]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 joinselect distinctselect 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子句中使用,但會在您的JOINSORDER BY子句中使用。 確保在表上有適當的索引,並且已定義了“ Pimary”和“ Foreign Key”。

可以使ColdFold9 SQL搜索查詢更快嗎?

是。 您要為受影響的列配置索引

Coldfusion不執行您的查詢。 它被傳遞到您的數據庫服務器以執行,然后將結果集傳遞回去。

您可以查詢並使用查詢分析器來生成執行計划,以查看查詢花費最多的時間。 您很可能需要在WHERE條件中使用的列上添加一些索引。 我相信在MySQL中,您可以使用EXPLAIN向您顯示缺少索引的位置http://dev.mysql.com/doc/refman/5.5/en/using-explain.html

  1. 嘗試在cl_ordersummary(studentID)上創建CREATE INDEX cl_ordersummary_studentID

  2. 其他索引也可以提供幫助,但是您必須使用前綴搜索進行此優化,SQL數據庫通常將前綴搜索轉換為索引范圍掃描。 例如,您可以索引電子郵件並將前綴用作參數:

  1. 全文搜索索引是優化的最佳選擇,有關RDBMS功能的信息,請參閱文檔。大多數數據庫都通過特殊功能或語法支持全文搜索。 您會在全文搜索中找到其他有用的功能,例如按最佳匹配進行排序。 如果將查詢更改為使用全文本搜索,則不需要選項2。

MySQL http://dev.mysql.com/doc/refman/5.0/en/fulltext-natural-language.html (所有主要數據庫都具有類似的搜索功能)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM