【发布时间】:2020-07-31 05:15:08
【问题描述】:
我有一个大表(大约 1000 万行),我需要删除“早于”10 天的记录(根据 created_at 列)。我有一个 python 脚本,我运行它来执行此操作。 created_at 是一个 varchar(255) 并且具有诸如 for 之类的值。 1594267202000
import mysql.connector
import sys
from mysql.connector import Error
table = sys.argv[1]
deleteDays = sys.argv[2]
sql_select_query = """SELECT COUNT(*) FROM {} WHERE created_at / 1000 < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL %s DAY))""".format(table)
sql_delete_query = """DELETE FROM {} WHERE created_at / 1000 < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL %s DAY)) LIMIT 100""".format(table)
try:
connection = mysql.connector.connect(host=localhost,
database=myDatabase,
user=admin123,
password=password123)
cursor = connection.cursor()
#initial count of rows before deletion
cursor.execute(sql_select_query, (deleteDays,))
records = cursor.fetchone()[0]
while records >= 1:
# stuck at following below line and time out happens....
cursor.execute(sql_delete_query, (deleteDays,))
connection.commit()
cursor.execute(sql_select_query, (deleteDays,))
records = cursor.fetchone()[0]
#final count of rows after deletion
cursor.execute(sql_select_query, (deleteDays,))
records = cursor.fetchone()[0]
if records == 0:
print("\nRows deleted")
else:
print("\nRows NOT deleted")
except mysql.connector.Error as error:
print("Failed to delete: {}".format(error))
finally:
if (connection.is_connected()):
cursor.close()
connection.close()
print("MySQL connection is closed")
当我运行这个脚本并且它运行 DELETE QUERY 但是......它失败了,原因是:
删除失败: 1205 (HY000): Lock wait timeout exceeded;尝试重启事务
我知道 innodb_lock_wait_timeout 当前设置为 50 秒,我可以增加它来克服这个问题,但是我宁愿不触碰超时......我想基本上删除也许是大块的?任何人都知道我可以在这里以我的代码为例吗?
【问题讨论】:
-
你有关于 created_at 的索引吗?
-
created_at 是什么类型?如果它是一个日期时间并被索引,这将更有效。
-
created_at 没有索引,是一个 varchar(255)
-
创建 MySQL 存储过程,删除旧行并简单地从 python 代码中调用它。如果删除的行数很大,并且这会影响其他用户,则按块删除(每个块 100 或 100 行)。
-
WHERE created_at / 1000 < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL %s DAY))- 这个条件是错误的,因为列值划分不允许使用该列的索引。将其转换为WHERE created_at < 1000 * UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL %s DAY))- 所有算术运算都移至常数部分,因此只计算一次,而不是为每个单独的行执行计算的原始形式。尽可能在条件中使用未更改的列值。
标签: python mysql database-cursor mysql-error-1205