2012-08-08 9 views
6

मेरे पास एक ऐसी साइट है जहां मुझे डेटा खोजने में सक्षम होना चाहिए और क्वेरी सभी उद्धरणों को अनदेखा करनी है। या न नहींएसक्यूएल सर्वर - खोज करते समय उद्धरणों को अनदेखा करने का कोई आसान तरीका है?

  1. के लिए खोज नहीं करते हैं, करते और शब्द है कि के साथ शुरू है कि पंक्तियों के लिए परिणाम प्राप्त: ऐसा नहीं, या न नहीं है"हैलो" या "हैलो" या हैलो और पुनः प्राप्त परिणामों पंक्तियों के लिए के लिए
  2. खोजें कि "हैलो", "हैलो" या हैलो

नोट:: शब्द है कि के साथ शुरू की है मैं पहले से ही खोज पद में पारित

मैं चाहता हूँ के लिए उद्धरण बाहर अलग करना हूँ अगर वहाँ की तुलना में एक आसान (या कम शब्द) विधि है पता करने के लिए:

select Name 
    from tbl_MyTable 
where (Replace(Replace(Replace(Replace(Replace(Replace(Name,'“',''),'‘',''),'''',''),'"',''),'’',''),'”','') like 'dont%' 
    or Replace(Replace(Replace(Replace(Replace(Replace(Name,'“',''),'‘',''),'''',''),'"',''),'’',''),'”','') like '% dont%'); 

अभी, मेरे सबसे अच्छे विचार एक नया स्तंभ बनाने के लिए है कि बोली-छीन संस्करण (एक स्थान के साथ prepended) ताकि मैं सिर्फ कर सकते हैं शामिल हैं:

select Name 
    from tbl_MyTable 
where FixedName like '% dont%'; 

लेकिन मैं वास्तव में जानना चाहते हैं कि यह एक नया स्तंभ बनाने के बिना पूरा किया जा सकता है और यह कुशल हो है चाहते हैं।

+0

मैं एक सी # ऐप से पूछताछ कर रहा हूं, इसलिए उस तरफ थोड़ा पैर-काम किया जा सकता है, लेकिन प्रदर्शन की लागत पर नहीं। मेरा कोड वास्तव में कई तालिकाओं और स्तंभों से पूछताछ कर रहा है (मैंने यहां मामला सरलीकृत किया है), इसलिए अधिमानतः मुझे डेटा-स्कोप्ड उत्तर चाहिए। –

उत्तर

1

तरह के बजाय एक प्रतिलिपि प्राप्त सूचकांक का प्रयोग करें।

http://msdn.microsoft.com/en-us/library/ms187317.aspx

CREATE UNIQUE INDEX ix1 ON tbl_MyTable(YourKey); //unique index required 
CREATE FULLTEXT CATALOG ft AS DEFAULT; // ft is your freetext catalog name 
CREATE FULLTEXT INDEX ON tbl_MyTable(Name) 
    KEY INDEX ix1 
    WITH STOPLIST = SYSTEM; // this is your index and allows you to run the command below 

तो आपकी क्वेरी चलाने के लिए इस का उपयोग करें::

SELECT Name 
FROM tbl_MyTable 
WHERE FREETEXT(Name, 'dont'); 

बात की इस तरह के सबसे तेजी से तकनीक है कि

अपने प्रतिलिपि प्राप्त सूचकांक बनाएँ। यदि आप तीसरे पक्ष के फ्री-टेक्स्ट इंजन का उपयोग करते हैं तो आप और भी तेज हो सकते हैं लेकिन इसके लिए शायद इसकी आवश्यकता नहीं है।

+0

तो समाधान होगा: 1) फिक्स्डनाम कॉलम बनाएं जो उद्धरण हटा देता है। 2) फिक्स्डनाम कॉलम पर पूर्ण पाठ अनुक्रमणिका बनाएं। 3) ... 4) लाभ? –

+0

नहीं, आपको उद्धरण हटाने की आवश्यकता नहीं है। नाम कॉलम पर बस अपनी पूर्ण पाठ अनुक्रमणिका बनाएं। मैंने इसे प्रतिबिंबित करने के लिए अपना उत्तर अपडेट कर दिया है। –

0

मैं एक उपयोगकर्ता परिभाषित समारोह बनाने इस तर्क को मजबूत करने का सुझाव देते हैं:

CREATE FUNCTION [dbo].[udf_StripQuotes] 
(
    @String VARCHAR(MAX) 
) 
RETURNS VARCHAR(MAX) 
AS 
BEGIN 
    RETURN Replace(
     Replace(
      Replace(
       Replace(
        Replace(
         Replace(@String,'“',''), 
        '‘',''), 
       '''',''), 
      '"',''), 
     '’',''), 
    '”','') 
END 
GO 

कौन सा तो दिखाई देता है: दक्षता, प्रमुख और अपने like बयान में % अनुगामी के रूप में

select Name 
from tbl_MyTable 
where dbo.udf_StripQuotes(name) like '% dont%'; 

जहां तक आपको किसी भी इंडेक्स का उपयोग करने से रोक देगा, जो एक पूर्ण टेबल स्कैन का कारण बन जाएगा ... यह शायद इस क्वेरी पर सबसे बड़ा प्रदर्शन है।

हालांकि, जैसे हारून स्पष्ट करता है, यह कार्यान्वयन यूडीएफ को कॉल करने के ऊपरी हिस्से के कारण मूल से धीमा होगा।

यदि आप अग्रणी वाइल्डकार्ड से बच सकते हैं, तो computed column with an index प्रदर्शन में सुधार करेगा।

अन्यथा, मुझे लगता है कि आपका दूसरा विकल्प Full-Text Search लागू करना होगा।

+0

यह निश्चित रूप से इसे समाहित करना और क्वेरी में फ़ंक्शन को संदर्भित करना आसान है, लेकिन केवल स्पष्ट होने के लिए, यह मूल की तुलना में धीमा, लेकिन शायद धीमा होने वाला है। –

+0

@AaronBertrand हम्म ... मैं सोच रहा था कि सबसे बड़ा प्रदर्शन हिट पूर्ण टेबल स्कैन से आएगा ... क्या आपको लगता है कि 'प्रतिस्थापन' कथन को एक udf में लपेटने से ध्यान देने योग्य ओवरहेड जोड़ा जाएगा? –

+0

ठीक है फ़ंक्शन को कॉल करने में ओवरहेड है, और आप स्कैन के दौरान फ़ंक्शन 2 एक्स पंक्ति गणना को कॉल करेंगे (क्योंकि कोई या शर्त है)। मैं उस जवाब में संबोधित करने जा रहा हूं जिसे मैं हटा दूंगा। –

0

यह प्रश्न का उत्तर नहीं है, लेकिन एक टिप्पणी के रूप में लागू करना वास्तव में कठिन होगा।

यदि आप स्वयं को क्वेरी को सरल बनाने के लिए यूडीएफ का उपयोग करने जा रहे हैं, तो अपने आप को एक पक्ष दें और आपके पास पंक्तियों की संख्या को सीमित करें, जो आपके पास नहीं है।बजाय:

where dbo.udf_StripQuotes(name) like 'dont%' 
    or dbo.udf_StripQuotes(name) like '% dont%'); 

यह करें:

where ' ' + dbo.udf_StripQuotes(name) like '% dont%'; 

जहां तक ​​मूल समस्या के रूप में, मैं माइकल के साथ सहमत हैं कि एक अनुक्रमित अभिकलन स्तंभ सबसे अच्छा हो सकता है, लेकिन यह करता है, तो नाम संभव नहीं होगा कॉलम 900 बाइट से अधिक है (और यह वाइल्डकार्ड के कारण जादुई रूप से स्कैन को एक खोज में बदल नहीं देगा, यह सिर्फ एक फ़ंक्शन कॉल करने की आवश्यकता को हटा देता है या क्वेरी में उन सभी को प्रतिस्थापित करता है)।

+0

उस कॉलम पर पूर्ण पाठ खोज समाधान हो सकता है? –

0

अंतरिक्ष या समय में कुशल?

आपका पहला समाधान अंतरिक्ष-कुशल है, लेकिन तालिका में प्रत्येक पंक्ति में एकाधिक स्ट्रिंग फ़ंक्शंस लगाने के कारण समय-अक्षम होने पर, प्रत्येक बार क्वेरी निष्पादित की जाती है।

जेनरेट किए गए कॉलम का समाधान स्पेस-अक्षम है, लेकिन एक बार स्ट्रिंग ऑपरेशंस को लागू करने के कारण समय-कुशल (जब आप कॉलम जोड़ते हैं और फिर सम्मिलित/अपडेट करते हैं)।

अपने उपयोगकर्ताओं के परिप्रेक्ष्य से, सबसे अच्छा समाधान जेनरेट किए गए कॉलम पर किए जाने वाले खोजों की संभावना है।

0

बिना किसी उद्धरण या डबल कोट्स के सभी नाम वापस लौटने के लिए निम्नलिखित का प्रयास करें। यह, जैसे बयानों की आवश्यकता को रोकने के अन्य स्तंभ के लिए आवश्यकता से बचने, और आपकी क्वेरी को गति देगा:

SELECT Replace(
    Replace(
     Replace(
      Replace(
       Replace(
        Replace(Name, '“', ''), 
       '‘', ''), 
      '''',''), 
     '"', ''), 
    '’',''), 
'”', '') AS Name 
FROM tbl_MyTable 
संबंधित मुद्दे

 संबंधित मुद्दे