2011-12-21 8 views
14

मैं कई क्षेत्रोंSQLite: 'searchstr%' को इंडेक्स का उपयोग करना चाहिए?

word_id — INTEGER PRIMARY_KEY 
word — TEXT 
... 

..और ~ 150k पंक्तियों के साथ एक डीबी की है।

चूंकि यह एक शब्दकोश है, इसलिए मैं मास्क 'search_string%' के साथ एक शब्द खोज रहा हूं। यह मेल खाने वाली पंक्तियों को खोजने के लिए 15ms लेते हुए ठीक काम करता था। तालिका में 'word' फ़ील्ड के लिए एक अनुक्रमणिका है। हाल ही में मैंने तालिका को संशोधित किया है (उस तालिका के कुछ फ़ील्ड जो दायरे से बाहर हैं) और कुछ हुआ - यह क्वेरी निष्पादित करने में 400ms ले रहा है, इसलिए मैं समझता हूं कि यह अब इंडेक्स का उपयोग करने में विफल रहता है। स्ट्रिंगफोर्ड क्वेरी = जैसे 10ms परिणाम दिखाता है। क्या किसी को पता है कि यहां क्या हो रहा है?

+0

मुझे ऐसा लगता है, शायद आप बी-पेड़ को देखना चाहते हैं क्योंकि बी-पेड़ श्रेणी क्वेरी में और तुलनात्मक रूप से कुशल हैं। – Jasonw

+0

हम्म, बी-पेड़ के निर्माण का मानना ​​नहीं है? तुम्हारा मतलब है, मुझे अपने आप से एक बी-पेड़ बनाना चाहिए? – nikans

+0

क्या% हमेशा आपके खोज शब्द के अंत में है, कभी शुरू नहीं होता? – mikel

उत्तर

25

इस मामले में एक अनुक्रमणिका का सुरक्षित रूप से उपयोग नहीं किया जा सकता है। एक अनुभवहीन कार्यान्वयन इस परिणत हो गया:

... WHERE word LIKE 'search_string%'

में

... WHERE word >= 'search_string' AND word < 'search_strinh'

खोज स्ट्रिंग का अंतिम वर्ण incrementing द्वारा। ऑपरेटरों की तुलना में अधिक से कम और कम सूचकांक का उपयोग कर सकते हैं, जहां LIKE नहीं कर सकता।

दुर्भाग्य से, यह सामान्य मामले में काम नहीं करेगा। LIKE ऑपरेटर केस-असंवेदनशील है, जिसका अर्थ है कि 'a' LIKE 'A' सत्य है। उपर्युक्त परिवर्तन पूंजीकृत अक्षरों के साथ किसी भी खोज स्ट्रिंग को तोड़ देगा।

कुछ मामलों में, हालांकि, आप जानते हैं कि केस संवेदनशीलता किसी विशेष कॉलम के लिए अप्रासंगिक है, और उपरोक्त परिवर्तन सुरक्षित है। इस मामले में, आपके पास दो विकल्प हैं।

  1. इस विशेष फ़ील्ड को कवर करने वाले इंडेक्स पर NOCASE कोटिंग अनुक्रम का उपयोग करें।
  2. बदलें PRAGMA case_sensitive_like = ON;

इन कार्यों के किसी भी चल पारदर्शी रूप से आप के लिए ऊपर परिवर्तन करने के लिए SQLite सक्षम हो जाएगा द्वारा LIKE ऑपरेटर कार्यक्रम चौड़ा के व्यवहार; आप हमेशा LIKE का उपयोग हमेशा करते रहें, और SQLite इंडेक्स का उपयोग करने के लिए अंतर्निहित क्वेरी को फिर से लिख देगा।

आप SQLite Query Optimizer Overview page पर "LIKE अनुकूलन" के बारे में अधिक पढ़ सकते हैं।

+1

अरे! उपरोक्त धागे में मैंने उल्लेख किया है कि मैंने कुछ पैरामीटर का उपयोग किया है जब मैंने पिछली बार इंडेक्स (जो काम किया) बनाया था। तो, वह 'कॉलेज नॉक' था। मैंने इसे खोजने के लिए 6 घंटे की तरह खर्च नहीं किया है। अच्छा लिंक, मैंने इसे भी पढ़ा है, लेकिन ऐसा लगता है कि यह सिर्फ मेरे ध्यान से फिसल गया है। धन्यवाद, होमर! आपने अभी मुझे बचाया है भगवान जानता है कि कितना समय है। – nikans

+0

मुझे लगता है कि आपका मतलब है 'PRAGMA case_sensitive_like = ON;' जैसा कि आपने कहा था, 'LIKE' डिफ़ॉल्ट रूप से असंवेदनशील है। लेख से आप लिंक करते हैं: "LIKE अनुकूलन तब हो सकता है जब ऑपरेटर के बाईं ओर नामित कॉलम को अंतर्निहित BINARY कोटिंग अनुक्रम और case_sensitive_like का उपयोग करके अनुक्रमित किया गया हो।" –

+0

आह, सच है। मैं इसे ठीक कर दूंगा। धन्यवाद! –

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