1

假设我有一个名为“users”的表。创建代码:

CREATE TABLE IF NOT EXISTS users 
(id_user INTEGER PRIMARY KEY AUTOINCREMENT, 
 username VARCHAR(32) COLLATE NOCASE, 
 passwd_hash VARCHAR(255) NOT NULL DEFAULT '', 
 passwd_salt VARCHAR(255) NOT NULL DEFAULT '', 
 email_addr VARCHAR(255) NOT NULL DEFAULT '');


CREATE INDEX IF NOT EXISTS idx_id_user ON users (id_user ASC);
CREATE INDEX IF NOT EXISTS idx_username ON users (username ASC);

当玩家加入服务器时,它会检查玩家的用户名是否已注册:

SELECT id_user 
FROM users 
WHERE username = '%s' LIMIT 1

如果用户名已注册,玩家将被要求登录。在登录尝试我有这个:

SELECT passwd_hash, passwd_salt 
FROM users 
WHERE id_user = %d

然后它显然会检查两个密码是否匹配。

所以我的问题是,应该passwd_hash并且应该passwd_salt被索引吗?

4

4 回答 4

4

我会创建一个三列索引:(userid、password_hash、password_salt)。这可以用作更高效率的覆盖指数

看起来这只是 SQLite 的一个小改进,但这个概念在其他可以在 RAM 中缓存索引的 RDBMS 实现中得到了更大的好处。

http://www.sqlite.org/queryplanner.html说:

1.7 覆盖指数
通过使用两列索引,“加利福尼亚橙子的价格”查询变得更加高效。但是 SQLite 可以使用包含“价格”列的三列索引做得更好:

这个新索引包含查询使用的原始 FruitsForSale 表的所有列 - 搜索词和输出。我们称之为“覆盖指数”。因为所需的所有信息都在覆盖索引中,SQLite 永远不需要查询原始表来查找价格。

因此,通过在索引末尾添加额外的“输出”列,可以避免必须引用原始表,从而将查询的二进制搜索次数减少一半。这是性能的恒定因素改进(大约是速度的两倍)。但另一方面,它也只是一种细化;两倍的性能提升并不像第一次索引表时看到的一百万倍的提升那么显着。对于大多数查询,1 微秒和 2 微秒之间的差异不太可能被注意到。

您可能有兴趣阅读我的演示文稿,如何设计索引,真的。我为 MySQL 用户做了那个演示,但这些概念也与 SQLite 和大多数其他 RDBMS 相关。

于 2013-07-28T18:04:41.080 回答
4

执行查询时:

SELECT passwd_hash, passwd_salt
FROM users
WHERE id_user = %d;

SQL 引擎将使用索引来查找正确的记录。然后它进入表本身以检索select子句所需的数据。

如果您改为将索引构建为:

CREATE INDEX IF NOT EXISTS idx_id_user ON users (id_user ASC, paswd_hash, passwd_salt);

然后 SQL 引擎只需使用索引就可以满足查询。这可以提供性能提升。收益将非常小。

这是一般原则,但也有例外。一些数据库支持数据列上的聚集索引的概念。在这样的索引中,表中的数据必须按键排序,表本身作为索引运行。但是,这不是 SQLite 索引选项。

于 2013-07-28T17:47:15.857 回答
1

不需要。您只需要索引要查询的列。

一旦找到记录,索引将无助于更快地检索该记录中的其他列。

于 2013-07-28T17:42:03.020 回答
0

我相信没有。您在 id_user 上创建了一个索引,足以有效地获取密码信息。当然,我们不会仅仅因为我们检索它就在每个字段上创建一个索引。

于 2013-07-28T17:54:40.253 回答