Php 我应该在一个页面中添加和删除索引吗?
假设我有Php 我应该在一个页面中添加和删除索引吗?,php,mysql,optimization,Php,Mysql,Optimization,假设我有玩家表。它由3行组成(有更多行,但假设只有3行)成员id、姓名、经验。我在每页中使用member\u id行,所以我只在member\u id中添加索引。但是我想在一个页面中列出一个最高exp的顶级玩家名单。所以我就这样做: $query = mysql_query("SELECT * FROM players ORDER BY `exp` DESC"); 如果我有10k名玩家,如果不向exp添加索引,我就不能像这样运行查询。所以我的问题是,我应该这样做: mysql_query("A
玩家
表。它由3行组成(有更多行,但假设只有3行)<代码>成员id、姓名、经验。我在每页中使用member\u id
行,所以我只在member\u id
中添加索引。但是我想在一个页面中列出一个最高exp
的顶级玩家名单。所以我就这样做:
$query = mysql_query("SELECT * FROM players ORDER BY `exp` DESC");
如果我有10k名玩家,如果不向exp
添加索引,我就不能像这样运行查询。所以我的问题是,我应该这样做:
mysql_query("ALTER TABLE `players` ADD INDEX ( `exp` )");
$query = mysql_query("SELECT * FROM players ORDER BY `exp` DESC");
mysql_query("ALTER TABLE `players` DROP INDEX `exp`");
或者我还能做些更好的事?因为添加和删除索引非常昂贵。但我可能可以每10分钟缓存一次,例如。绝对不行
构建索引比扫描整个表花费更多的时间,因此会严重降低性能
只需构建一次索引,然后将其保留。使用“一次性”索引
已生成索引
O(n)
-在排序中,但是您在插入和更新exp列时有O(log(n))
额外的时间
O(n)
比O(n*log(n))+O(n)
快得多,然后生成索引并保留此项,但如果对exp
的更改比ORDER by exp
多得多,则需要考虑不要为该列编制索引,因为它的总长度更长。或者使用其他解决方案,如SELECT
按exp
缓存排序
可能SELECT
的缓存结果是该问题的最佳解决方案,但在不添加和删除索引的情况下执行此选择,因为这没有任何意义。artifact是正确的,更糟糕的是,更改表是一个阻塞过程,这意味着所有的选择和更新都会在这期间堆积起来。如果您的数据库上有任何类型的负载,这将破坏它。要么使用索引,要么不使用,但不要构建和销毁索引
SELECT * FROM players ORDER BY `exp` DESC
这需要读取整个表并对其进行排序
mysql_query("ALTER TABLE `players` ADD INDEX ( `exp` )");
$query = mysql_query("SELECT * FROM players ORDER BY `exp` DESC");
mysql_query("ALTER TABLE `players` DROP INDEX `exp`");
这需要读取整个表,对其进行排序,将排序结果写入磁盘,从磁盘读回,然后删除它们:所有这些都需要锁定表
第一个选项速度更快,并发性更好
如果您创建一个永久索引,它会更快
10k
记录太少,不必担心DML的性能。但是如果我缓存它并每10分钟运行一次这个查询?会这么糟糕吗?因为添加大量索引会使我的更新
查询变慢,我想。@hey:你是不是每秒要向players
表写入数百次?不要让对更新性能的毫无根据的担忧驱使您扭曲整个应用程序。好的。您不想在exp
上建立永久索引的原因是什么?(顺便说一句,如果我的网站使用db凭据,允许它修改模式,这会让我感到紧张。)
mysql_query("ALTER TABLE `players` ADD INDEX ( `exp` )");
$query = mysql_query("SELECT * FROM players ORDER BY `exp` DESC");
mysql_query("ALTER TABLE `players` DROP INDEX `exp`");