2011-06-21 15 views
8

के साथ SQLiteParameter का उपयोग कर मुझे SQLiteParameters और LIKE ऑपरेटर का उपयोग SQLite क्वेरी में कोई समस्या है। यहां कोड का एक स्निपेट है, और अगर मेरे पास पर्याप्त कोड नहीं है तो मैं क्षमा चाहता हूं। यदि ऐसा है, तो मैं आसानी से और पोस्ट कर सकता हूं।SQLite.NET प्रदर्शन LIKE ऑपरेटर

गरीब प्रदर्शन:

using (OdysseyDataContext entities = new OdysseyDataContext()) 
{ 
    var results = entities.SearchResults.SqlQuery(
     "SELECT * FROM SearchResults WHERE ContactName LIKE @ContactName", 
     new SQLiteParameter("@ContactName", "test") 
    ); 
} 

महान प्रदर्शन:

using (OdysseyDataContext entities = new OdysseyDataContext()) 
{ 
    var results = entities.SearchResults.SqlQuery(
     string.Format(
      "SELECT * FROM SearchResults WHERE ContactName LIKE '{0}'", 
      "test" 
     ) 
    ); 
} 

अन्य महत्वपूर्ण कोड:

public class OdysseyDataContext : DbContext 
{ 
    public DbSet<SearchResult> SearchResults { get; set; } 
} 

public class SearchResult 
{ 
    [Key] 
    public Guid Id { get; set; } 
    public string ContactName { get; set; } 
} 

पहला उदाहरण निष्पादित करने के लिए 700 एमएस लेता है, जो अपने पर्यवेक्षक अस्वीकार्य पाता है। दूसरा उदाहरण निष्पादित करने के लिए 7 एमएस लगता है। अंतर क्यों? क्या मुझे कुछ नौसिखिया स्थिति कमाने के लिए पूरी तरह से गलत कर रहा है?

अग्रिम धन्यवाद!

+1

क्या आप कैशिंग कलाकृतियों को खत्म करने के लिए कई परीक्षण चला रहे हैं? क्या वे दोनों एक ही पंक्तियों को वापस करते हैं? क्या आप वाइल्डकार्ड का उपयोग कर रहे हैं? – Tim

+0

इसके अलावा, SQLite के कार्यान्वयन में जहां LIKE फ़ंक्शन ओवरराइड किया गया है, अनुक्रमणिका अनुपलब्ध हैं। आप किसके साथ मिलते हैं ... जहां संपर्क नाम GLOB @contactname [केस संवेदनशील, बीटीडब्लू]? – Tim

+0

हाय टिम। हाँ, मैं कई परीक्षण चला रहा हूँ। पहली बार 1 सेकंड से थोड़ा अधिक और 15 से अधिक परीक्षण औसत 700 एमएस है। हां, वे एक ही पंक्तियों को वापस करते हैं।नहीं, मैं किसी भी जंगली कार्ड का उपयोग नहीं कर रहा हूँ। मुझे पता है कि यह अजीब लगता है, लेकिन मैं केस संवेदनशील खोज को हटाने के लिए इस तरह के कथन का उपयोग कर रहा हूं ताकि यह ContactName COLOTATE NOCASE पर मेरे इंडेक्स सेटअप का उपयोग करेगा। – Terry

उत्तर

2

तो, मुझे लगता है कि मैं System.Data.SQLite के साथ किसी समस्या के लिए नीचे संकुचित हो सकता है लायक है। मैं C++ निम्नलिखित कोड की कोशिश की:

#include "sqlite3.h" 
#include <stdio.h> 

void xProfile(void* pArg, const char* query, sqlite3_uint64 pTimeTaken) 
{ 
    printf("%s\n", query); 
    printf("%I64d ms\n", pTimeTaken/1000000); 
} 

void PoorPerformance(); 
void GoodPerformance(); 

int main() 
{ 
    printf("Poor Performance:\n"); 
    PoorPerformance(); 

    printf("Good Performance:\n"); 
    GoodPerformance(); 

    return 0; 
} 

void PoorPerformance() 
{ 
    int rc; 
    int rowCount = 0; 

    sqlite3 *db; 
    if (sqlite3_open("<<File Here>>", &db)) 
    { 
     printf("Could not open the database."); 
     return; 
    } 

    sqlite3_profile(db, &xProfile, NULL); 

    sqlite3_stmt *statement; 
    if (!sqlite3_prepare_v2(db, "SELECT * FROM SearchResults WHERE ContactName LIKE @ContactName;", -1, &statement, 0)) 
    { 
     int result = 0; 
     int parameterIndex = sqlite3_bind_parameter_index(statement, "@ContactName"); 
     sqlite3_bind_text(statement, 1, "test", -1, NULL); 
     while (result != SQLITE_DONE) 
     { 
      result = sqlite3_step(statement); 

      if (result == SQLITE_ROW) 
      { 
       rowCount++; 
      } 
     } 

     sqlite3_finalize(statement); 
    } 

    printf("%d rows\n", rowCount); 

    sqlite3_close(db); 
} 

void GoodPerformance() 
{ 
    int rc; 
    int rowCount = 0; 

    sqlite3 *db; 
    if (sqlite3_open("<<File Here>>", &db)) 
    { 
     printf("Could not open the database."); 
     return; 
    } 

    sqlite3_profile(db, &xProfile, NULL); 

    sqlite3_stmt *statement; 
    if (!sqlite3_prepare_v2(db, "SELECT * FROM SearchResults WHERE ContactName LIKE 'test';", -1, &statement, 0)) 
    { 
     int result = 0; 

     while (result != SQLITE_DONE) 
     { 
      result = sqlite3_step(statement); 

      if (result == SQLITE_ROW) 
      { 
       rowCount++; 
      } 
     } 

     sqlite3_finalize(statement); 
    } 

    printf("%d rows\n", rowCount); 

    sqlite3_close(db); 
} 

दोनों PoorPerformance और GoodPerformance कार्यों 11 पंक्तियों के साथ 1 एमएस सामने आए। क्या मैंने किया है और सिस्टम.डाटा.क्यूलाइट द्वारा क्या किया जाना चाहिए के बीच कुछ अलग है? उम्मीद है कि यह कुछ ऐसा है जो मैं System.Data.SQLite के साथ एक बग के रूप में रिपोर्ट कर सकता हूं और शायद अपना स्वयं का फ़िक्स लागू कर सकता हूं।

+0

क्या आपके पास System.Data.SQLite के साथ आपकी समस्या पर कोई अपडेट है? – Shrike

+0

@Shrike नीचे मेरा जवाब देखें .. यह उपयोग का हो सकता है। – user1032657

1

चूंकि मैं दो प्रश्नों के बीच कोई अंतर नहीं देख पा रहा हूं, लेकिन तथ्य यह है कि वह स्क्लिटेपेरामीटर का उपयोग करता है और दूसरा स्ट्रिंग के रूप में एक पूर्ण एसक्यूएल-स्टेटमेंट - मैं सिर्फ आपकी समस्या को गुमराह करता हूं और that पर ठोकर खा जाता हूं।

वहां यह इंगित करता है कि SQLiteCommand ऑब्जेक्ट पर ParameterCheck नामक एक संपत्ति है, जो कुछ प्रदर्शन हानि का कारण बन सकती है।

आप SQLiteCommand ऑब्जेक्ट को पास करने के लिए अपने कोड को फिर से लिखने का प्रयास कर सकते हैं और पैरामीटर चेक संपत्ति को गलत पर सेट कर सकते हैं। मुझे लगता है कि आपको कुछ गति हासिल करनी चाहिए।

कम से कम यह एक शॉट :)

+0

मैं इतना उम्मीद कर रहा था कि इससे मेरी समस्या हल हो जाएगी! दुर्भाग्यवश यह System.Data.SQLite की बजाय Devart.Data.SQLite का उपयोग करता है। – Terry

0

मेरे पास System.Data.SQLite के साथ प्रदर्शन समस्याएं भी हैं, जिनमें से कुछ मैं संबोधित करने और सुधारने में सक्षम हूं, और अन्य मेरे पास नहीं है।

हालांकि, हाल ही में मैं इस विकल्प सी # SQLite पुस्तकालय की खोज: http://code.google.com/p/csharp-sqlite/

यह मुझे कोई प्रदर्शन के मुद्दों दिया है, और मैं वास्तव में एक मौजूदा परियोजना में इस एक (वाक्य रचना में लगभग कोई परिवर्तन के साथ System.Data.SQLite प्रतिस्थापित - मैंने कम या ज्यादा सचमुच डीएलएल और उपयोग निर्देशों को प्रतिस्थापित किया .. वहां कुछ पंक्तियां थीं जहां मुझे कुछ टाइप करना था), और यह आश्चर्यजनक रूप से चीजों को बढ़ा दिया। ऐसे समय थे जहां मैं System.Data.SQLite के साथ सेकंड के क्रम पर इंतजार कर रहा था, और अब निष्पादन तत्काल हैं।

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