2017-08-08 39 views
0

使用SQLite版本3如何访问只有一行而不在内存中存储整个表?

enter image description here

我呼吁这个命令ExecuteScalar方法: command.CommandText = "SELECT Val FROM TableName WHERE Id = 2";

的问题是,当我用存储器中读取软件来访问的内存空间,我应用程序,我可以在Val列中找到存储在此表中的所有3个字符串。

鉴于Id列是主键,我怎么能得到第二Val细胞(a60fd4d5-83d0-4665-9250-329ec6d498d4),而无需访问和存储在存储器中的另外两个Val细胞?

访问只有一行而不访问表中其余行的正确SQL命令是什么?

注:我不问如何访问表中的单个记录/行。我知道如何做到这一点,我问如何在不将整个表存储在应用程序的内存空间的情况下访问它。假设我有1000万行,而我只想访问1行,我不希望全部1000万行存储在内存中。

+2

您的SQL命令不是问题。你有没有检查你的表是如何索引的? –

+0

我该如何检查?或者我怎么才能控制,当我创建数据库? – IneedHelp

+0

https://sqlite.org/lang_createindex.html –

回答

2

数据库文件组织成页面,默认大小为4 KB。 尝试从磁盘读取较小的部分是没有意义的(因为这是文件系统现在使用的默认块大小),并且在很多情况下,increasing the page size会提高性能。

如果您想检查数据库没有访问比所需更多的行,请查看EXPLAIN QUERY PLAN的输出。 如果您确实想使用该内存读取软件,请确保您的表格大于一页;确保至少有几兆字节。 (对于少于几兆字节,任何类型的优化都是毫无意义的。)

+0

我的担心不在于性能,而是与安全性有关。我不希望用户能够在内存字符串中找到我没有明确访问的字符串。 实际上,在填充好几页之后,其他页面的数据并没有存储在内存中,所以这对于性能来说是件好事,但它仍然不能解决我的问题。但我猜测没有我想要的解决方案。 – IneedHelp

+0

当用户可以访问SQLite使用的内存时,他也可能直接读取数据库文件。如果你有安全装置,你必须加密一切。 –

+0

是的,一切都是加密的,我只是想阻止用户能够从我选择的记录在同一页上的内存字符串中拉出。 – IneedHelp

1

提供Id是表的关键,它是聚簇索引或唯一的非聚簇索引,您使用的是正确的语法。

除非您有严重的性能问题,否则尝试对SQL Server进行配置文件毫无意义。

这是过早的优化。

SQL Server针对性能进行了大量优化,编写它的团队知道他们在做什么。

如果我不得不冒险猜测你所看到的,我会说SQL Server已经遵循索引b-tree &已经到达叶页。然后它将整个页面读入内存。在8KB的情况下,这不是很多数据。这个每页8KB的值经过精心挑选,以平衡性能和存储成本等其他因素。 然后它返回该页面上所需插槽中的数据。

就你而言,这只是该页面的1个插槽。

由于您的示例数据很小,因此所有行都可能位于同一页面上。

+0

Ashley,OP没有使用SQL Server。他正在使用SQLite。 –

+0

我的错误是,我通常浏览SQL Server&C#标签。其他人可能有更好的答案,但我猜测大多数RDBMS具有类似的内部结构,如用于索引管理的B树,并且一次读取整个叶节点。 –

+0

@AshleyPillaythanks花时间,upvoted。 – IneedHelp

相关问题