出于身份验证目的拆分“用户”表是个好主意吗?

Ali*_*eza 8 mysql mysql-5 authentication

假设我的站点中有一个用户表,其中表中有大约 2-3 百万个用户(记录)。

为了加快我的登录过程,拆分我的用户表是否是一种好方法,一个用于他们的信息,另一个用于他们的登录。

如果我们可以从一张表中运行类似于下面的查询:

select username,password from users where username=`test` AND password=****
Run Code Online (Sandbox Code Playgroud)

是否有必要拆分它,这是否会加快我网站的登录过程?

Rol*_*DBA 10

恕我直言,您不需要将其物理拆分。然而,缓存它会很好。

如果该users表使用 MyISAM 存储引擎,那么您就有一个很好的优势。

由于 MyISAM 只缓存索引,你可以做两件事

  • 您可以创建一个自定义键缓存只是为了加载users表的MyISAM 索引
  • 您可以索引用户名和密码以强制查询仅命中该自定义密钥缓存

确保存在以下索引 users

ALTER TABLE users ADD UNIQUE INDEX username_ndx (username);
ALTER TABLE users ADD UNIQUE INDEX username_password_ndx (username,password);
Run Code Online (Sandbox Code Playgroud)

这两个索引有两(2)个主要原因

索引 #1 的原因

索引username_ndx可以防止一个用户名有多个密码,也可以防止多个用户使用相同的名称

索引 #2 的原因

该索引username_password_ndx提供了一个覆盖索引。因此,您的查询将仅在自定义 MyISAM 缓存中查找用户名和密码,而不是检查表。

更多关于覆盖索引原则的链接

接下来是实际创建自定义密钥缓存。以下是创建 8MB 密钥缓存并加载该专用密钥缓存的命令(示例:如果表为mydb.users):

SET GLOBAL authentication_cache.key_buffer_size = 1024 * 1024 * 8;
CACHE INDEX mydb.users IN authentication_cache;
LOAD INDEX INTO CACHE mydb.users;
Run Code Online (Sandbox Code Playgroud)

您应该将这三行放在文件 /var/lib/mysql/startup.sql 中

将此添加到 /etc/my.cnf

[mysqld]
init-file=/var/lib/mysql/startup.sql
Run Code Online (Sandbox Code Playgroud)

这将在每次启动 mysql 时加载缓存

试一试 !!!

更新 2011-12-30 17:25 EDT

如果您想获得设置缓存的确切大小,请使用以下查询:

SELECT CONCAT('1024 * 1024 * ',ROUND(index_length/power(1024,2))) RecommendedCacheSize
FROM information_schema.tables WHERE table_name='users';
Run Code Online (Sandbox Code Playgroud)

更新 2011-12-30 23:21 EDT

这里是一个基于InnoDB的方法

你仍然需要索引

ALTER TABLE users ADD UNIQUE INDEX username_ndx (username);
ALTER TABLE users ADD UNIQUE INDEX username_password_ndx (username,password);
Run Code Online (Sandbox Code Playgroud)

您必须确保 InnoDB 缓冲池具有可用的用户名和密码。您可能不得不在 mysql 启动时进行完整的索引扫描:

步骤 1) 创建 ReadUserPass.sql

echo "select username,password from users;" > /var/lib/mysql/ReadUserPass.sql
Run Code Online (Sandbox Code Playgroud)

步骤 2) 将该脚本添加到 /etc/my.cnf

[mysqld]
init-file=/var/lib/mysql/ReadUserPass.sql
Run Code Online (Sandbox Code Playgroud)

步骤 3) 执行以下操作之一

  • $ service mysql restart
  • mysql> source /var/lib/mysql/ReadUserPass.sql

由于这两个列(用户名和密码)都位于 中username_password_ndx,因此构成该索引的所有索引页都被重新加载到 InnoDB 缓冲池中。这是必要的,因为有可能会刷新索引页。为了尽量减少这种情况的发生,请增加缓冲池大小并重新启动 mysql(一次)。


mrd*_*nny 5

不需要拆分包含几百万行的表。性能调优应该通过索引来完成。MySpace 在一个表中列出了数亿个帐户,并且该表的性能很好。(在 MySpace 使用高峰期,我是他们的 DBA。)这种情况下的表可能有 80-90 字节宽(可能多一点)。