目前我有一个用php编写的更新逻辑,它可以更新mysql数据库中的多个表。每当执行某个php脚本时,更新逻辑检查数据库是否是最新的(基于保存在其他地方的版本标志),如果不是,则应用所有必要的更新。
更新逻辑的一部分应为特定表列添加索引:
if ($database_version < 1337) {
if (!get_results("SHOW INDEX FROM my_table WHERE Key_name = 'my_key';")) {
query("ALTER TABLE my_table ADD INDEX(my_key);");
}
set_database_version(1337);
}
如您所见,我执行以下设置:
检查数据库是否低于特定的版本标志
如果是:检查表my\u table中是否存在键my\u key的索引
如果不是:创建索引
更新数据库的版本标志
现在假设更新逻辑是由用户触发的。因为表非常大,所以创建索引可能需要一段时间。在创建索引之前,另一个用户触发更新逻辑。因为索引还没有完成,所以初始检查返回false,并且更新逻辑为该索引启动另一个创建查询—这意味着索引被构建/创建了两次,甚至更频繁。
首先,我假设在创建索引的过程中,在表中填充值之前,会将一个特定的条目放入表中。但事实似乎并非如此,因为
SHOW INDEX FROM my_table WHERE Key_name = 'my_key';
即使此索引刚刚创建,也返回false。
我的问题是:有没有一种方法可以通过mysql/php来检查索引是否存在或刚刚创建,这样我就可以防止它被多次创建?
2条答案
按热度按时间3gtaxfhh1#
-----尚未发布5.7.0里程碑10--添加或更改的功能-------
如果创建的索引与现有索引重复,或者在严格sql模式下出现错误,服务器现在会发出警告(臭虫#37520,臭虫#11748842)
所以,。。。
至少更新到5.7
启用严格模式
检查错误。
或者,翻遍
information_schema.KEY_COLUMN_USAGE
以发现是否存在等效索引。68bkxrlz2#
有一种方法可以查看mysql中的索引创建进度,如下所述:https://www.percona.com/blog/2014/02/26/monitor-alter-table-progress-innodb_file_per_table/.
但我想,如果能以更简单的方式实现这一目标,那就太难了。
我的建议是保持沉默
lock
每当用户要创建索引时设置变量。当其他用户尝试执行脚本时lock
如果变量已设置或未设置,则会对其进行检查,并且仅当未设置时,脚本才会前进以创建索引。