我首先说我是C#和SQL的初学者,很抱歉,如果我的代码包含一些垃圾。
我是一个日语词典的sqlite表 它有以下几行:
ID :唯一的自动增量整数; 单词:日语中的单词"表意文字" (es。:元気);
阅读:单词的语音阅读(es。:げんき);
定义:字典定义这个词;
单词可能会在字典中出现不止一次 有时可能会有多个条目,其中" word"和#34; reding"是相同的,我需要检索所有这些:
ID - 单词 - 阅读 - 定义
1 - 爱 - あい - 爱;
2 - 爱 - あい - 1800本书的标题......;
这是我检索结果的方法:
void Search(string _word, string _reading) //es.: Search(愛, あい);
{
...
using(var conn = new SQLiteConnection("Data Source=dictsdb.sqlite;Version=3;"))
{
conn.Open();
string sql = "SELECT * FROM dictionary WHERE word = '" + _word + "' AND reading = '" + _reading + "'";
using(var command = new SQLiteCommand(sql, conn))
{
using(var reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while(reader.Read())
{
(...)
}
}
}
conn.Close();
}
...
}
字典没有按特定方式排序,因此我无法使用优化的搜索算法 我无法对字典进行排序,因为我需要它的实际顺序。
缓慢的部分是command.ExecuteReader()
我想因为每次搜索都必须检查字典的所有条目,这是巨大的。
有什么建议让它更快?
编辑:谢谢大家的建议!索引技巧解决了这个问题,现在快了几倍!还要感谢其他建议,比如参数化输入!答案 0 :(得分:2)
首先,祝贺你开始了第一个C#/ SQLite项目,祝你好运。我建议稍微调整一下你的数据。例如:
1)表格结构。听起来你的单词之间存在多对一的关系 - >阅读定义。意思是,你有很多阅读可能会多次使用相同的工作。然后,您可以重构表结构以表示类似这样的内容:
JD_Word JD_Reading
|------------| |------------|
| ID | |----->| ID |
| Word | | | Reading |
| Reading ID |--| |------------|
| Definition |
|------------|
2)索引。通常,创建简单索引可能是个好主意。作为概述,索引减少了数据库必须扫描的数据页数。在SQLite中,您的主键应自动编入索引。有关GetFileAttributes的更多信息。您可以在JD_Reading表上创建多列索引:
当前结构:
CREATE INDEX dictionary_word ON dictionary(word);
具有多列的当前结构
CRAETE INDEX dictionary_word ON dictionary(word, reading);
here(见第一点):
CREATE INDEX dictionary_word ON JD_Word(Word);
CREATE INDEX dictionary_reading ON JD_Reading(Reading);
3)还有很多其他选择!查看3NF突出显示一些C#/ SQLite性能问题。如果您有任何问题,请发表评论。快乐的编程。
答案 1 :(得分:1)
要加快查询速度,请在dictionary
表格中添加一个索引,至少包含word
列(reference):
CREATE INDEX IdxDictionary ON dictionary(word);
根据每个单词的读数数量,可能值得将性能与多列索引的性能进行比较:
CREATE INDEX IdxDictionary ON dictionary(word, reading);
多列索引占用的空间比第一列多;如果存储无关紧要,你可以创建第二个。
当我们假设_word
和_reading
都是用户输入时,需要对它们进行参数化以防止用户入侵您的数据库:
string sql = "SELECT * FROM dictionary WHERE word=@word AND reading=@reading";
using(var command = new SQLiteCommand(sql, conn))
{
command.Parameters.AddWithValue("@word", _word);
command.Parameters.AddWithValue("@reading", _reading);
...
}
如果预期匹配的数量很高,您可以进一步优化:仅提取ID
和definition
列,word
和reading
是多余的。