2016-11-22 110 views
2

我有一張員工表(約450萬),其中有一列叫做job_titledomain如何改進我的選擇查詢以使其更快?

我希望能夠創建並運行動態查詢,以根據職位名稱選擇特定的員工,並且其域也位於提供的域數組內。

它是如何工作的,是在前端用戶結束了域的大陣列(任何地方從200 - 10000),他們然後輸入兩件事情:他們希望

  1. 哪個職稱包括
  2. 他們想要的職稱排除

因此,我們再建立一個最終看起來像這樣的查詢:

SELECT employee_id 
FROM employee 
WHERE (
     domain LIKE '%shetlandfoods.co.uk' 
     OR domain LIKE '%example1.co.uk' 
     OR domain LIKE '%example2.co.uk' 

     -- About 50 additional domains in this list 

     OR domain LIKE '%example50.co.uk' 
    ) 
    AND (job_title LIKE '%Manager%' OR job_title LIKE '%Director%') 
    AND (job_title NOT LIKE '%Assistant%') 

注意域的列表非常長,並且可以包括數以千計的域名(的!))現在

,這樣的查詢需要約230秒,與大約180只有域!想象一下使用數千個;它會一直持續下去。

我想知道是否有任何方法可以優化/更改此查詢以使其運行速度更快?還是有什麼我可以做的數據庫?

+0

'大部分是剛域,所以只是跳到結束'所有那些無索引的LIKE過濾器可能是問題所在。 –

+0

「域」數據的來源是什麼?您能向我們展示幾個樣本嗎?我的想法是,也許你可以以某種方式預處理這些數據,以使查詢更容易。 –

+0

專業提示:SQL可以包含換行符;-) –

回答

3

這裏有兩個選項讓人想起(第二個建議由@paul上面在他的評論中)。

其中之一是,您可以預處理domain列中的數據,使其僅包含確切的域,而不包含其他任何內容。這是一個衆所周知的問題,並且在Java或JavaScript中相對容易處理。如果這樣做的話,那麼你可以把一個索引的domain列,並使用一個WHERE條款看起來像如下:

WHERE domain IN ('shetlandfoods.co.uk', 
       'alac.shetland.co.uk', 
       'malakofflimited.co.uk', 
       ...) 

另一種選擇可能是域的反向比較反對的條款的反你在原來的WHERE條款,例如

WHERE REVERSE(domain) LIKE 'ku.oc.sdoofdnaltehs%' OR 
     REVERSE(domain) LIKE 'ku.oc.dnaltehs.cala%' OR 
     REVERSE(domain) LIKE 'ku.oc.detimilffokalam%' OR 
     ... 

你甚至可以存儲domain從您的應用程序/ UI層的背面,這樣你就不必強制MySQL計算反向爲WHERE子句中每個術語。

我可能會傾向於第一種選擇,假設您有足夠的帶寬來在訪問MySQL之前提取域。

+1

** REVERSE(域名)**不是最好的方法。將** REVERSE(域)**值存儲在新字段中好得多。比你可以使用索引。在你的情況下,它始終是一個全表掃描 –

+0

我有一個同名'域'和'job_title'上的索引。 – ThePerplexedOne

+0

@BerndBuffen我建議在MySQL之外計算和存儲反向。我更喜歡在應用程序層中提取真正的域名,然後再與equals進行比較。在這種情況下,索引應該加快速度。 –

0

您可以創建臨時表爲這種情況如下:

CREATE TEMPORARY TABLE domain_values (
    domain_value VARCHAR(100) 
); 

然後插入的所有域爲:

INSERT INTO domain_values VALUES ('%shetlandfoods.co.uk'), ('%shopshetlandtoday.co.uk'), ........; 

然後作爲選擇:

SELECT e.employee_id FROM employee e JOIN domain_values d ON (e.domain LIKE d.domain_value) AND 
    (e.job_title LIKE '%Manager%' OR e.job_title LIKE '%Director%') AND (e.job_title NOT LIKE '%Assistant%'); 
+0

這樣做的好處是什麼? – ThePerplexedOne

+0

這將比上述效率更高。 –

0

逆轉像

WHERE REVERSE(domain) LIKE 'ku.oc.sdoofdnaltehs%' OR REVERSE(domain) LIKE 'ku.oc.dnaltehs.cala%' OR REVERSE(domain) LIKE 'ku.oc.detimilffokalam%'...

是一種選擇,你可以嘗試另一種,你也可以嘗試這個

SELECT employee_id FROM employee WHERE INSTR(domain,'shetlandfoods.co.uk') > 0

這是更快然後LIKE %text%