[英]SQLite.NET Performance Using SQLiteParameter with LIKE operator
I am having an issue using SQLiteParameters and the LIKE operator in a SQLite query. 我在SQLite查询中使用SQLiteParameters和LIKE运算符时遇到问题。 Here is a snippet of code, and I apologize if I don't have enough code here. 这是一段代码,如果这里没有足够的代码,我深表歉意。 If that is the case, I can easily post more. 如果是这样,我可以轻松发布更多。
Poor Performance: 表现不佳:
using (OdysseyDataContext entities = new OdysseyDataContext())
{
var results = entities.SearchResults.SqlQuery(
"SELECT * FROM SearchResults WHERE ContactName LIKE @ContactName",
new SQLiteParameter("@ContactName", "test")
);
}
Great Performance: 很棒的演出:
using (OdysseyDataContext entities = new OdysseyDataContext())
{
var results = entities.SearchResults.SqlQuery(
string.Format(
"SELECT * FROM SearchResults WHERE ContactName LIKE '{0}'",
"test"
)
);
}
Other important code: 其他重要代码:
public class OdysseyDataContext : DbContext
{
public DbSet<SearchResult> SearchResults { get; set; }
}
public class SearchResult
{
[Key]
public Guid Id { get; set; }
public string ContactName { get; set; }
}
The first example takes 700 ms to execute, which my supervisor finds unacceptable. 第一个示例需要700毫秒来执行,我的主管认为这是不可接受的。 The second example takes 7 ms to execute. 第二个示例需要7毫秒才能执行。 Why the difference? 为什么会有所不同? Is there something I am doing completely wrong to earn me newbie status? 为获得新手身份,我在做些完全错误的事情吗?
Thanks in advance! 提前致谢!
So, I think I may have narrowed it down to an issue with System.Data.SQLite. 因此,我想我可能已将其范围缩小到System.Data.SQLite的问题。 I tried the following code in C++: 我在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);
}
Both the PoorPerformance and GoodPerformance functions yielded 1 ms with 11 rows. PoorPerformance和GoodPerformance函数的结果都是1毫秒(11行)。 Is there something different between what I did and what should have been done by System.Data.SQLite? 我所做的事情和应该由System.Data.SQLite完成的工作之间有什么不同吗? Hopefully this is just something I can report as a bug with System.Data.SQLite and perhaps apply my own fix. 希望这只是我可以报告为System.Data.SQLite的错误并可能应用我自己的修复程序的东西。
Since I cannot see any difference between the two queries, but the fact, that one uses sqliteparameter and the other one a complete sql-statement as string - I just googled your problem and stumbled upon that . 因为我看不出这两个查询之间的事实,另一个完整的SQL语句作为字符串的任何区别,但是,一个使用sqliteparameter -我只是用Google搜索你的问题,偶然发现那 。
There it indicates that on the SQLiteCommand object there is a property called ParameterCheck , which can cause some performance loss. 那里表明在SQLiteCommand对象上有一个名为ParameterCheck的属性,这可能会导致性能下降。
You could try to rewrite your code to pass a SQLiteCommand object and set the ParameterCheck property to false. 您可以尝试重写代码以传递SQLiteCommand对象,并将ParameterCheck属性设置为false。 I think you should gain some speed doing this. 我认为您应该这样做。
At least it's worth a shot :) 至少值得一试:)
I have also had performance issues with System.Data.SQLite, some of which I have been able to address and improve, and others I have not. 我还遇到了System.Data.SQLite的性能问题,其中一些我已经能够解决和改进,而另一些我没有。
However, recently I discovered this alternative C# SQLite library: http://code.google.com/p/csharp-sqlite/ 但是,最近我发现了这个替代的C#SQLite库: http : //code.google.com/p/csharp-sqlite/
It has given me no performance issues, and I actually replaced System.Data.SQLite with this one in an existing project (almost no changes in syntax - I more or less literally just replaced the DLL and the using directive.. there were a couple lines where I had to typecast something), and it sped things up marvelously. 它没有给我带来任何性能问题,实际上我在现有项目中用这个替换了System.Data.SQLite(语法几乎没有变化-我或多或少实际上只是替换了DLL和using指令。。在我不得不打字的地方排成一行),它使事情变得异常快。 There were times where I was waiting on the order of seconds with System.Data.SQLite, and now the executions are instantaneous. 有时候我在等待使用System.Data.SQLite的秒级命令,现在执行是瞬时的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.