2012-08-08 132 views
0

我在我的應用程序中有很多像這樣的查詢;SQL索引優化查詢

SELECT DISTINCT STREET_NUMBER, STREET_NAME 
FROM leads 
WHERE STREET_NAME || ',' || SUBURB IN (select VAL from streetFilter) 
    AND USER_ID IN (%@) 
    AND TIMESTAMP >= '%@' 
    AND TIMESTAMP <= '%@' 
    AND GEO_LAT <> '0' 
ORDER BY STREET_NAME, CAST(`STREET_NUMBER` AS SIGNED) ASC 

我的問題是,它的值或值的集合我應該添加索引來。

到目前爲止,我剛剛添加的一切,即CREATE INDEX temp在引線( '見下文')

  1. (STREET_NUMBER,STREET_NAME)
  2. (街道,郊區)
  3. (STREET_NAME | | '' ||郊區)
  4. (USER_ID)
  5. (時間戳)
  6. (GEO_LAT)
  7. (STREET,SUBURB,USER_ID,TIMESTAMP,GEO_LAT)
  8. (STREET_NAME || ','||郊區,USER_ID,時間戳,GEO_LAT)
  9. (STREET_NAME)
  10. (STREET_NUMBER)
  11. (CAST(STREET_NUMBER AS簽名))
  12. (STREET_NAME,STREET_NUMBER)
  13. (STREET_NAME,CAST(STREET_NUMBER AS SIGNED ))

但我知道這是不對的。 任何人都可以指出哪些不起作用,或不會讓我的查詢更快,哪些將?

數據庫是SQLite的

我創建語句: @「CREATE TABLE IF NOT EXISTS引線(LEAD_ID BIGINT PRIMARY KEY,USER_ID INTEGER,GEO_LAT,GEO_LONG,CUSTOMER_NAME,UNIT_NUMBER,STREET_NUMBER,STREET_NAME,郊區,州,郵編INTEGER,NMI,DPI_MIRN,STATUS,STATUS_INT INTEGER,OUTCOME INTEGER,OUTCOME_FULL INTEGER,FINAL_CODE INTEGER,NOTES,NOTES_EXTRA,TIMESTAMP)「];

719130; 50; -32.933871; 151.774978;先生大衛李; 1; 34;利姆諾斯PDE;新城疫; NSW; 2300 ;;; P:0; 0 ;; 0 ;; 0:0:0; 20120602174036 719233; 50; -32.9307183; 151.7803428; Mitch James先生; 1; 1-7; TYRRELL ST; THE HILL; NSW; 2300 ;;; P; 0; 0 ;; 0 ;; 0:0:0; 20120602174036 719234 ; 50; -32.933155; 151.777351; Ben Foster先生;; 4; BINGLE ST; NEWCASTLE; NSW; 2300; 41021027208; 52404368858; C; 0; 0 ;; 0 ;; 0:0:0; 20120602174036 719300; 50; -32.9291125; 151.785025; Ms Marilyn Rajakulenthiran; U 12; 3; KING ST; NEWCASTLE; NSW; 2300 ;;; P; 0; 0; 0 ;; 0:0:0; 20120602174036

查詢現在是SELECT LEAD_ID,USER_ID,UNIT_NUMBER,STREET_NUMBER,STREET_NAME,SUBURB,STATE,POSTCODE,STATUS_INT,OUTCOME,CUSTOMER_NAME,NOTES FROM leads JOIN outcomeF ilter ON leads.OUTCOME = outcomeFilter.VAL JOIN suburbFilter ON leads.SUBPOST = suburbFilter.VAL WHERE USER_ID IN(%@)AND TIMESTAMP BETWEEN'%@'AND'%@'ORDER BY SUBURB,STREET_NAME,CAST(STREET_NUMBER已簽名)

我的初始狀態仍然沒有改善。似乎是最慢的順序

+1

我願意賭一個閃亮的一分錢,你可以通過將這個子選擇改寫爲一個連接來獲得一些改進。 – 2012-08-08 05:39:00

+0

抱歉,馬克不是這次。我的查詢現在是SELECT LEAD_ID,USER_ID,UNIT_NUMBER,STREET_NUMBER,STREET_NAME,SUBURB,STATE,POSTCODE,STATUS_INT,OUTCOME,CUSTOMER_NAME,NOTES FROM leads JOIN outcomeFilter ON leads.OUTCOME = outcomeFilter.VAL JOIN suburbFilter ON leads.SUBPOST = suburbFilter.VAL WHERE USER_ID IN(%@)AND TIMESTAMP BETWEEN'%@'AND'%@'ORDER BY SUBURB,STREET_NAME,CAST('STREET_NUMBER' as SIGNED)。我也嘗試添加更多的索引,但仍然沒有比我開始時更快。我認爲很多問題都來自最後的排序。有任何想法嗎? – davidelias16 2012-08-08 07:06:10

回答

0

最好的辦法是查看查詢執行計劃並檢查返回的索引是什麼。索引太多和/或在錯誤的地方實際上可能會損害性能,這是適得其反的。

要訪問的執行計劃:

在查詢菜單上,單擊顯示執行計劃,然後運行在查詢窗口查詢 。執行計劃和查詢結果現在出現在窗口的 單獨窗格中,以便您可以一起查看它們。

+0

運行* this *查詢的執行計劃只會告訴您索引將幫助* this *查詢而不是其他查詢,並且不會像其他插入成本那樣說話。 – 2012-08-08 05:40:32

+0

@RobertHarvey - 正確。根據問題標題和OP指出他創建了一切索引,我的重點是索引。 – RobB 2012-08-08 05:41:41

+0

我已經完成了執行計劃,但我不知道它的含義。我得到addr,opcode,p1,p2,p3,p4,p5,註釋列和134行,但無法做出任何意義 – davidelias16 2012-08-08 06:36:08

0

那麼你在表中的幾乎所有字段都有範圍掃描。

我建議看說明,然後看是否如下令它變得更好:

create index lookup_idx on leads(user_id, timestamp, geo_lat). 

如果你正在使用MySQL,你將無法使用該索引,以便利用geo_lat部分(user_id,時間戳)。 Oracle可以在範圍內執行SKIP SCANS,因此如果使用Oracle,請將geo_lat保留在索引中。

讓我們確切地知道您正在使用哪個數據庫,併發布EXPLAIN PLAN(然而您獲得它用於該RDBMS)和CREATE TABLE以便我們可以看到發生了什麼。

編輯注意到這是SQLlite。在這種情況下可能是(user_id,timestamp),但我可以稍後使用SQLfiddle進行檢查。

請再次發佈CREATE TABLE和一些示例數據。

0

一般而言,您只需要在涉及搜索,排序,加入或WHERE條件的字段中使用索引(可能)。表格中有幾個不屬於這些類別的字段;這些字段的索引可以安全地消除而不會對查詢的性能產生負面影響。

運行執行計劃會告訴您是否有任何屬於這些類別之一的字段的索引也是不必要的。例如,如果字段的基數很小(即只有很少的唯一值),那麼索引不會有幫助。

有關SQLite特定優化和索引使用的更多信息,請訪問:http://www.sqlite.org/optoverview.html。值得注意的是:SQLite將在查詢中爲每個表使用至多一個索引。請參閱Choosing between multiple indices。 ANALYZE命令將幫助您確定哪些指數最有價值。

+0

我嘗試使用BETWEEN作爲時間戳,但它似乎使其變慢。我可以在哪些其他領域之間使用或哪些適合? – davidelias16 2012-08-08 06:37:15