我有一个本地SQLite数据库
表详情
-- Describe PREFIX_LIST
CREATE TABLE PREFIX_LIST(ITEM VARCHAR(25) PRIMARY KEY)
-- Describe SUFFIX_LIST
CREATE TABLE SUFFIX_LIST(ITEM VARCHAR(25) PRIMARY KEY)
-- Describe VALID_LIST
CREATE TABLE VALID_LIST (
"PART1" TEXT,
"PART2" TEXT,
PRIMARY KEY(PART1, PART2)
)
现在这个列表非常庞大,我需要从中保存数据。
这是我的实施。
SQLiteConnection con = null;
SQLiteCommand cmd = null;
Connect(DbPath, ref con, ref cmd);
cmd.CommandText =
"SELECT PART1 || '@' || PART2 FROM VALID_LIST
WHERE NOT EXISTS
(SELECT * FROM PREFIX_LIST WHERE VALID_LIST.PART1 LIKE '%' || ITEM || '%')
AND NOT EXISTS
(SELECT * FROM SUFFIX_LIST WHERE VALID_LIST.PART2 LIKE '%' || ITEM || '%')";
var reader = cmd.ExecuteReader();
if (reader.HasRows)
{
string savePath;
if (SaveTextFile(out savePath) == DialogResult.OK)
{
TextWriter writer = new StreamWriter(savePath);
while (reader.Read())
{
writer.WriteLine(reader.GetString(0));
}
writer.Close();
writer.Dispose();
}
}
reader.Close();
reader.Dispose();
cmd.Dispose();
con.Close();
con.Dispose();
MessageBox.Show("List Saved!.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
我需要更好的方法来更快地保存列表。 VALID_LIST 中的总条目数为2639117
并且花了15分钟为上面的SQL QUERY保存它!
如果可以优化sql查询,请lmk!
提前致谢
答案 0 :(得分:6)
除非通配符附加到后缀,否则LIKE
的查询通常会非常慢。诸如LIKE '%foo'
之类的谓词不能通过典型的字符串索引编制索引。
但是,您可以使用full text search(FTS)功能替换sqlite中繁重的LIKE
用法。
FTS3和FTS4扩展模块允许用户创建特殊的 具有内置全文索引的表(以下称为“FTS表”)。该 全文索引允许用户有效地查询数据库 所有包含一个或多个单词的行(以下称为“标记”),即使 该表包含许多大型文档。
他们的an example在您的用例表现方面看起来很有前途。
CREATE VIRTUAL TABLE enrondata1 USING fts3(content TEXT); /* FTS3 table */
CREATE TABLE enrondata2(content TEXT); /* Ordinary table *
SELECT count(*) FROM enrondata1 WHERE content MATCH 'linux'; /* 0.03 seconds */
SELECT count(*) FROM enrondata2 WHERE content LIKE '%linux%'; /* 22.5 seconds */
答案 1 :(得分:2)
考虑使用全文搜索。
要使其工作,必须对PREFIX和SUFFIX中的值进行标记化(它们必须是单独的单词),并且您尝试匹配的ITEM必须是其中一个值中的不同标记(不是一两个字或两个字)。例如,PREFIX和SUFFIX中的字符串必须是“RED BLUE GREEN”或“DOG,CAT,CAPYBARA”,而ITEM的值必须是RED,BLUE,GREEN,DOG,CAT或CAPYBARA。
如果满足这些条件,您可以启用全文搜索,将这些表重新创建为全文表,并将MATKE(和通配符)替换为MATCH。在这种情况下,SQLite将在PREFIX或SUFFIX中找到的每个标记上维护索引,并且搜索的部分将更快,更快。
不幸的是,在SQlite中启用FTS涉及从源代码编译产品,并设置一个或多个编译时标志。我没有这方面的经验。
答案 2 :(得分:0)
我不确定这是否是你想要的,但它有助于加快写入过程。尝试在字符串生成器中累积从数据库中读取的字符串,然后写入文件。 例如,您可以读取100k字符串,然后立即将100k写入文件。
StringBuilder builder = new StringBuilder();
int count = 0; //to limit the number of rows stored in string builder.
while (reader.Read())
{
builder.AppendLine(reader.GetString(0));
count++;
//store every 100k or so rows at once.
//This number depends on how much RAM
//you can allocate towards storing the string of rows.
//If you have 2GB of free RAM
//this number can easily be 1 million but it always depends on the
//size of each string stored in database.
if(count == 100000)
{
File.AppendAllText(path, builder.ToString()); //Append all rows to the file
builder.Clear(); //clear the string for next 100k rows of data
count = 0; //Clear the counter value
}
count++
}
如果有帮助,请告诉我。