2011-11-04 71 views
1

從這個具體情況的工作中,我發現邏輯運算符在SQL中沒有短路。SQL 2008:在不需要時防止在查詢中進行全文查找

我經常做的東西沿着這些路線在where子句(通常與搜索查詢交易時)在:

WHERE 
    (@Description IS NULL OR @Description = myTable.Description) 

其中,即使它不是短路在這個例子中,其實並不重要。但是,在處理全文搜索功能時,它確實很重要。如果該查詢的第二部分是CONTAINS(myTable.Description, @Description),它將不起作用,因爲這些函數不允許該變量爲空或爲空。

我發現的CASEWHEN語句是順序執行的,所以在需要的時候,我可以改變我的查詢,像這樣以確保全文查詢只調用,以改變由零變到'""'沿時,它是空來允許查詢執行:

WHERE 
    (CASE WHEN @Description = '""' THEN 1 WHEN CONTAINS(myTable.Description, @Description) THEN 1 ELSE 0 END = 1) 

上面的代碼應防止全文查詢片從執行,除非確實存在具有搜索的值。

我的問題是,如果我運行此查詢,其中@Description爲'""',儘管該表和搜索沒有結束,但在處理聚集索引搜索和fulltextmatch的執行計劃中仍有相當多的時間一直在使用:有什麼辦法可以避免這種情況?

我試圖從一個硬編碼的動態查詢中找出這個問題並存入存儲過程,但是如果程序結束速度變慢,我不確定我能證明它的正確性。

回答

0

如果其他人遇到這樣的情況,這就是我最終做的事情,這與M_M的情況非常接近;我掙開全文片,把它們樹枝背後:

DECLARE @TableBfullSearch TABLE (TableAId int) 
IF(@TableBSearchInfo IS NOT NULL) 
    INSERT INTO @TableBfullSearch 
    SELECT 
     TableAId 
    FROM 
     TableB 
    WHERE 
    ...(fulltext search)... 

DECLARE @TableCfullSearch TABLE (TableAId int) 
IF(@TableCSearchInfo IS NOT NULL) 
    INSERT INTO @TableCfullSearch 
    SELECT 
     TableAId 
    FROM 
     TableC 
    WHERE 
    ...(fulltext search)... 

--main query with this addition in the where clause 
SELECT 
    ... 
FROM 
    TableA 
WHERE 
    ... 
    AND (@TableBSearchInfo IS NULL OR TableAId IN (SELECT TableAId FROM @TableBfullSearch)) 
    AND (@TableCSearchInfo IS NULL OR TableAId IN (SELECT TableAId FROM @TableCfullSearch)) 

我認爲這大概是好,因爲它會得到沒有某種形式的動態查詢

0

它的效果並不理想,但也許像這樣的工作:

IF @Description = '' 
BEGIN 
    SELECT ... 
END 
ELSE 
BEGIN 
    SELECT ... 
    WHERE CONTAINS(mytable.description, @Description) 
END 

這樣可以避免mysql和也運行FT Scan的不需要的時候。

作爲一些一般筆記,我通常發現CONTAINSTABLE要快一點。此外,由於無論您是使用我的解決方案還是您的解決方案,查詢計劃都會有很大不同,請留意parameter sniffing。參數嗅探是優化器根據傳入的特定參數值構建計劃時的情況。

+0

這會得到一個有點冒險,因爲在查詢中有2個這樣的可選查詢,所以我最終得到4個分支 – John