Vraag Trage SQL-query met betrekking tot CONTAINS en OR


We hebben een probleem, we hoopten dat de goede mensen van Stack Overflow ons hiermee konden helpen. We gebruiken SQL Server 2008 R2 en ondervinden problemen met een query die zeer lang duurt om te worden uitgevoerd op een gematigde set gegevens, ongeveer 100.000 rijen. We gebruiken CONTAINS om in xml-bestanden te zoeken en LIKE in een andere kolom om toonaangevende jokers te ondersteunen.

We hebben het probleem gereproduceerd met de volgende kleine query die ongeveer 35 seconden in beslag neemt:

SELECT something FROM table1 
WHERE (CONTAINS(TextColumn, '"WhatEver"') OR  
        DescriptionColumn LIKE '%WhatEver%')

Zoekopdrachtplan:

Slow query

Als we de bovenstaande query wijzigen in plaats van UNION, daalt de bedrijfstijd van 35 seconden naar <1 seconde. We willen voorkomen dat deze aanpak wordt gebruikt om het probleem op te lossen.

SELECT something FROM table1 WHERE (CONTAINS(TextColumn, '"WhatEver"') 
UNION
(SELECT something FROM table1 WHERE (DescriptionColumn LIKE '%WhatEver%'))

Zoekopdrachtplan:

Fast query

De kolom die we CONTAINS gebruiken om door te zoeken is een kolom met afbeelding van het type en bestaat uit xml-bestanden met een grootte van 1K tot 20K.

We hebben geen goede theorieën over waarom de eerste vraag zo traag is, dus we hoopten dat iemand hier iets verstandigs te zeggen zou hebben. De vraagplannen laten voor zover wij weten niets ongewoons zien. We hebben ook de indexen en statistieken opnieuw opgebouwd.

Is er iets overduidelijk dat we hier over het hoofd zien?

Alvast bedankt voor je tijd!


10
2018-06-30 11:54


oorsprong


antwoorden:


Waarom gebruik je DescriptionColumn LIKE '%WhatEver%' in plaats van CONTAINS(DescriptionColumn, '"WhatEver"')?

CONTAINS is uiteraard een predikaat in de volledige tekst en zal de SQL Server Full-Text-engine gebruiken om de zoekresultaten te filteren LIKE is een "normaal" SQL Server-sleutelwoord en dus zal SQL Server de Full-Text-engine niet gebruiken voor asist met deze query - in dit geval omdat de LIKE termijn begint met een wildcard SQL Server kan geen indexen gebruiken om te helpen met de query, wat hoogstwaarschijnlijk resulteert in een tafelscan en / of slechtere prestaties dan het gebruik van de fulltext-engine.

Haar moeilijk onmogelijk om te vertellen zonder een uitvoeringsplan, maar mijn inschatting van wat er zou gebeuren, zou zijn:

  • De UNION variatie van de query is het uitvoeren van een tabel scan tegen table1 - de tafelscan is niet snel, maar omdat er relatief weinig rijen in de tabel zijn, presteert deze niet dat langzaam (vergeleken met een 35s-benchmark).

  • In de OR variatie van de query SQL Server gebruikt eerst de fulltext-engine om te filteren op basis van de CONTAINS en vervolgens een RDI-zoekopdracht uitvoert op elke overeenkomende rij in het resultaat om te filteren op basis van de LIKE predicaat, echter om de een of andere reden heeft SQL Server het aantal rijen massaal onderschat (dit kan gebeuren met bepaalde soorten predikaat) en gaat dus door met het uitvoeren van enkele thousnad RDI-lookups die uiteindelijk ongelooflijk traag zijn (een tafelscan zou veel sneller zijn geweest) ).

Om echt te begrijpen wat er aan de hand is, moet je een vraagplan ontvangen.


4
2018-06-30 12:23



Hebben jullie dit geprobeerd:

SELECT *
FROM table
WHERE CONTAINS((column1, column2, column3), '"*keyword*"')  

In plaats van dit:

SELECT *
FROM table
WHERE CONTAINS(column1, '"*keyword*"') 
OR CONTAINS(column2, '"*keyword*"') 
OR CONTAINS(column3y, '"*keyword*"') 

De eerste is een stuk sneller.


1
2018-03-30 12:35



Ik kwam dit gewoon tegen. Dit is naar verluidt een fout op SQL Server 2008 R2:

http://www.arcomit.co.uk/support/kb.aspx?kbid=000060

Uw benadering om een ​​UNION van twee selecties te gebruiken in plaats van een OF is de oplossing die zij in dat artikel aanbevelen.


1
2018-06-14 15:20