5

मेरे पास ऐसे लोगों के नाम हैं जो वर्तमान में 35 मिलियन पंक्तियां हैं। मुझे यह जानने की जरूरत है कि इन नामों को तेज़ी से खोजने के लिए सबसे अच्छी विधि क्या है। वर्तमान प्रणाली (मेरे द्वारा डिज़ाइन नहीं की गई) में, केवल पहले और अंतिम नाम कॉलम अनुक्रमित हैं और SOUNDEX का उपयोग करने के अतिरिक्त विकल्प के साथ "LIKE" क्वेरी का उपयोग करते हैं (हालांकि मुझे यकीन नहीं है कि यह वास्तव में बहुत अधिक उपयोग किया जाता है)। प्रदर्शन हमेशा इस प्रणाली के साथ एक समस्या रहा है, और इसलिए वर्तमान में खोज 200 परिणामों तक सीमित हैं (जो अभी भी चलाने में बहुत अधिक समय लेती हैं)। तो, मेरे पास कुछ प्रश्न हैं:एसक्यूएल सर्वर खोज उचित नाम पूर्ण पाठ सूचकांक बनाम LIKE + SOUNDEX

  1. क्या पूर्ण पाठ अनुक्रमणिका उचित नामों के लिए अच्छी तरह से काम करती है?
  2. यदि हां, तो उचित नाम पूछने का सबसे अच्छा तरीका क्या है? (कंटेनर, FREETEXT, आदि)
  3. क्या कोई अन्य सिस्टम (Lucene.net की तरह) है जो बेहतर होगा?

बस संदर्भ के लिए, मैं डेटा एक्सेस के लिए फ्लुएंट एनएचबेर्नेट का उपयोग कर रहा हूं, इसलिए इसके साथ काम करने वाली विधियों को प्राथमिकता दी जाएगी। मैं वर्तमान में SQL सर्वर 2008 का उपयोग कर रहा हूँ।

संपादित मैं जोड़ने के लिए है कि मैं बहुत समाधान है कि आमतौर पर गलत वर्तनी नाम जैसी चीजों के साथ सौदा होगा में रुचि है, जैसे 'Smythe', 'स्मिथ', साथ ही पहला नाम है, जैसे 'टॉमस' कर रहा हूँ चाहता हूँ ' थॉमस '।

क्वेरी योजना से ऊपर के लिए

|--Parallelism(Gather Streams) 
     |--Nested Loops(Inner Join, OUTER REFERENCES:([testdb].[dbo].[Test].[Id], [Expr1004]) OPTIMIZED WITH UNORDERED PREFETCH) 
      |--Hash Match(Inner Join, HASH:([testdb].[dbo].[Test].[Id])=([testdb].[dbo].[Test].[Id])) 
      | |--Bitmap(HASH:([testdb].[dbo].[Test].[Id]), DEFINE:([Bitmap1003])) 
      | | |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([testdb].[dbo].[Test].[Id])) 
      | |   |--Index Seek(OBJECT:([testdb].[dbo].[Test].[IX_Test_LastName]), SEEK:([testdb].[dbo].[Test].[LastName] >= 'WHITDþ' AND [testdb].[dbo].[Test].[LastName] < 'WHITF'), WHERE:([testdb].[dbo].[Test].[LastName] like 'WHITE%') ORDERED FORWARD) 
      | |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([testdb].[dbo].[Test].[Id])) 
      |   |--Index Seek(OBJECT:([testdb].[dbo].[Test].[IX_Test_FirstName]), SEEK:([testdb].[dbo].[Test].[FirstName] >= 'THOMARþ' AND [testdb].[dbo].[Test].[FirstName] < 'THOMAT'), WHERE:([testdb].[dbo].[Test].[FirstName] like 'THOMAS%' AND PROBE([Bitmap1003],[testdb].[dbo].[Test].[Id],N'[IN ROW]')) ORDERED FORWARD) 
      |--Clustered Index Seek(OBJECT:([testdb].[dbo].[Test].[PK__TEST__3214EC073B95D2F1]), SEEK:([testdb].[dbo].[Test].[Id]=[testdb].[dbo].[Test].[Id]) LOOKUP ORDERED FORWARD) 

एसक्यूएल:

CREATE INDEX IX_Test_Name_DOB 
ON Test (LastName ASC, FirstName ASC, BirthDate ASC) 
INCLUDE (and here I list the other columns) 

मेरे खोज अब कर रहे हैं:

SELECT * FROM testdb.dbo.Test WHERE LastName LIKE 'WHITE%' AND FirstName LIKE 'THOMAS%' 

मिच से सलाह के आधार पर, मैं इस तरह एक सूचकांक बनाया मेरी सामान्य खोज (आखिरी, पहली, और जन्म तिथि) के लिए अविश्वसनीय रूप से तेज़।

+0

क्या आप टीएसक्यूएल भी पोस्ट कर सकते हैं? –

उत्तर

5

निर्भर करता है कि आपकी पसंद की तरह क्या दिखता है।

यदि आप LIKE '%abc%' खोज रहे हैं तो कोई अनुक्रमणिका का उपयोग नहीं किया जा सकता है, जबकि LIKE 'abc%' की खोज करते समय एक अनुक्रमणिका का उपयोग किया जा सकता है। इसके अलावा, अगर प्रथम और अंतिम नाम पर इंडेक्स (एसएस) उत्सर्जित क्वेरी को 'कवर' नहीं कर रहा है तो कुंजी लुकअप (बुकमार्क लुकअप) का प्रदर्शन किया जाएगा और प्रदर्शन पर महत्वपूर्ण प्रभाव डाला जाएगा।

क्या आपकी अनुक्रमणिका नियमित रूप से पुनर्निर्मित हैं?

क्या आपके पास एक उदाहरण क्वेरी योजना है?

अद्यतन: एक क्वेरी के लिए एक कवर इंडेक्स वह है जिसका उपयोग WHERE मानदंडों को करने के लिए किया जा सकता है और शेष कॉलम सूची जैसे शेष क्वेरी को पूरा करने के लिए आवश्यक सभी स्तंभ भी हैं।

Using Covering Indexes to Improve Query Performance

अद्यतन: भले ही आप (के बाद से lastname अधिक चयनात्मक होना चाहिए) (Lastname, Firstname) पर एक समग्र सूचकांक बनाने के लिए, सभी स्तंभों के लिए एक देखने ('*' कॉलम सूची) अभी भी आवश्यक हो जाएगा टेबल क्लस्टर सूचकांक में।

+0

सूचकांक नियमित रूप से पुनर्निर्मित किया जाएगा, शायद साप्ताहिक। मैं लगभग 5,000 प्रति दिन की दर से रिकॉर्ड जोड़ रहा हूं। हा, ऐसा लगता है कि वर्तमान प्रणाली "पसंद" का उपयोग नहीं कर रही है, जाहिर है बहुत धीमी है। तो, मैं कहूंगा कि 'एबीसी%' में सुधार होना चाहिए। –

+0

'कवर' से आपका क्या मतलब है? –

+0

यह वास्तव में सहायक है, मिच। मैं आपके लिए एक उदाहरण क्वेरी योजना प्राप्त करने पर काम कर रहा हूं। तो, क्या मुझे एक एकल इंडेक्स बनाना चाहिए जिसमें सभी कॉलम शामिल हैं? –

0

यदि आप पहले नाम और अंतिम नाम कॉलम पर एक अनुक्रमणिका बनाते हैं, तो LIKE का उपयोग करके सटीक मिलान खोज और उपसर्ग खोज तेजी से तेज हो जाएंगी।

(MySQL में, "सूचकांक का उपयोग LIKE तुलना के लिए भी किया जा सकता है यदि LIKE का तर्क एक सतत स्ट्रिंग है जो वाइल्डकार्ड वर्ण से शुरू नहीं होता है।" मुझे लगता है कि एमएस एसक्यूएल का एक समान नियम है, लेकिन एमएस की जांच करें एसक्यूएल दस्तावेज सुनिश्चित करने के लिए।)

साउंडएक्स खोजों को तेज़ करने के लिए, पहले नाम के साउंडएक्स संस्करण को स्टोर करें और अंतिम नाम नए कॉलम स्टोर करें, और उन कॉलम पर इंडेक्स बनाएं।

1

मुझे ध्वनि पसंद नहीं है। मुझे लगता है कि एल्गोरिदम के नए पुनरावृत्तियों बेहतर हैं, लेकिन आप अंग्रेजी भाषा में हर शब्द को काफी हद तक कम कर रहे हैं। यह समय के साथ झूठे मैचों का एक टन उत्पन्न करता है। मैंने मेटाफोन पढ़ा है और इसके उत्तराधिकारी डबल मेटाफोन बेहतर हैं, लेकिन मेरे पास उनके साथ सीधा अनुभव नहीं है।

मिच का like का कवरेज बहुत अच्छी तरह से है, इसलिए मैं इसे दोहराने वाला नहीं हूं।

+0

ध्वनि के बारे में जानकारी के लिए धन्यवाद। –

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