我有一个mysql查询,需要6天以上才能完成,activation\u member表中大约有2.5亿条记录,temp\u message\u split表中大约有190万条记录。正在查找有关调整此查询的帮助:
UPDATE TEMP_MESSAGE_SPLIT A,
(SELECT
ACTIVATION_MEMBER_KEY,
dh_member_id,
alt_id,
drsn
FROM ACTIVATION_MEMBER AM ) B
SET A.ACTIVATION_MEMBER_KEY = B.ACTIVATION_MEMBER_KEY, A.STATUS = 'U'
WHERE A.DH_MEMBER_ID = B.DH_MEMBER_ID OR ( (A.ALT_ID = b.alt_id) AND (A.DRSN = b.drsn)) ;
update查询用于更新temp\u message\u split表中已存在于activation\u member表中的所有成员的temp\u message\u split.status='u'。我们需要优化这个查询,以便它将需要尽可能短的时间来执行。
表create语句:
CREATE TABLE
activation_member
(
ACTIVATION_MEMBER_KEY bigint NOT NULL AUTO_INCREMENT,
PORTAL_STATEMENT_LOC_KEY bigint,
FIRST_NAME VARCHAR(20),
LAST_NAME VARCHAR(30),
DOB DATE,
EMPLOYEE_ID VARCHAR(20),
CES_CUST_NUM VARCHAR(7),
MED_POLICY_NUM VARCHAR(20),
EMAIL_ADDR VARCHAR(50),
DH_MEMBER_ID VARCHAR(9),
ALT_ID VARCHAR(20),
DRSN VARCHAR(2),
SSN VARCHAR(9),
EPIPHANY_MEMBER_ID bigint,
SYSTEM_HIS_CNT mediumint,
SYSTEM_USER VARCHAR(30),
SYSTEM_TIMESTAMP DATETIME,
PRIMARY KEY (ACTIVATION_MEMBER_KEY),
CONSTRAINT ACTIVATION_MEMBER_FK1 FOREIGN KEY (PORTAL_STATEMENT_LOC_KEY) REFERENCES
`portal_statement_loc` (`PORTAL_STATEMENT_LOC_KEY`),
INDEX ACTIVATION_MEMBER_IDX1 (PORTAL_STATEMENT_LOC_KEY),
INDEX ACTIVATION_MEMBER_IDX2 (DH_MEMBER_ID),
INDEX ACTIVATION_MEMBER_IDX3 (EMPLOYEE_ID, FIRST_NAME, MED_POLICY_NUM, DOB),
INDEX ACTIVATION_MEMBER_IDX4 (EPIPHANY_MEMBER_ID),
INDEX ACTIVATION_MEMBER_IDX5 (ALT_ID, DRSN)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE
portal_statement_loc
(
PORTAL_STATEMENT_LOC_KEY bigint NOT NULL AUTO_INCREMENT,
PORTAL_ADDRESS VARCHAR(200),
STATEMENT_VENDOR VARCHAR(100),
SYSTEM_HIS_CNT mediumint,
SYSTEM_USER VARCHAR(30),
SYSTEM_TIMESTAMP DATETIME,
PRIMARY KEY (PORTAL_STATEMENT_LOC_KEY)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE
temp_message_split
(
FIRST_NAME VARCHAR(20),
LAST_NAME VARCHAR(30),
DOB VARCHAR(10),
EMPLOYEE_ID VARCHAR(20),
CES_CUST_NUM VARCHAR(7),
MED_POLICY_NUM VARCHAR(20),
EMAIL_ADDR VARCHAR(50),
DH_MEMBER_ID VARCHAR(9),
ALT_ID VARCHAR(20),
DRSN VARCHAR(2),
SSN VARCHAR(9),
EPIPHANY_MEMBER_ID VARCHAR(18),
PORTAL_ADDRESS VARCHAR(30),
STATEMENT_VENDOR VARCHAR(20),
CONTENT_KEY VARCHAR(18),
EPIPHANY_COMMUNICATION_ID VARCHAR(200),
PRIORITY VARCHAR(4),
DAYS_UNTIL_EXPIRED VARCHAR(4),
CONTENT_DTL_KEY VARCHAR(18),
STATUS VARCHAR(1),
ACTIVATION_MEMBER_KEY bigint,
MESSAGE_BOARD_KEY bigint,
PORTAL_STATEMENT_LOC_KEY bigint,
temp_message_split_KEY bigint NOT NULL AUTO_INCREMENT,
PRIMARY KEY (temp_message_split_KEY),
INDEX EPIPHANY_COMMUNICATION_ID_IDX (EPIPHANY_COMMUNICATION_ID),
INDEX TEMP_MESSAGE_SPLIT_IDX1 (DH_MEMBER_ID),
INDEX TEMP_MESSAGE_SPLIT_IDX2 (ALT_ID),
INDEX TEMP_MESSAGE_SPLIT_IDX3 (DRSN)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
2条答案
按热度按时间m0rkklqb1#
我认为正确的更新应该是:
6yt4nkrj2#
使用多表
UPDATE
JOIN
没有子查询(如果可能)。请使用
JOIN ... ON
语法而不是旧的“commajoin”语法。而不是使用
OR
,做两个UPDATEs
. 如果我们能为查询设计足够的索引,那么每次更新都会运行得更快。这可能是正确的语法:
对于其中一个表(或者添加到两个表中,因为我不知道是否有一个表是首选):
处理必须完全扫描一个表,然后将(“嵌套循环联接”)延伸到另一个表中。
UPDATE
(或DELETE
)由于保存行以便在发生崩溃或错误时撤消,大量行的删除可能需要很长时间ROLLBACK
. 要考虑做的一件事就是UPDATEs
一次1000行。本文讨论如何有效地做到这一点。