MariaDB 内部连接很慢

MariaDB Inner join is slow

这是我的SQL(有解释):

EXPLAIN
UPDATE
    VF_KRED kred
INNER JOIN GBI gbi ON
    kred.vendor = gbi.vendor
INNER JOIN MASTER_DATA master_data ON
    master_data.vendor_code = gbi.vendor 
SET
kred.GBI_VAL_REP =
(CASE
    WHEN kred.country = 'JP' THEN
    CASE
        WHEN gbi.WITHHOLD_TAX_CODE = 0 THEN 2
        WHEN gbi.WITHHOLD_TAX_CODE = 'IN' THEN 1
    END
    ELSE
    CASE
        WHEN gbi.WITHHOLD_TAX_CODE = master_data.REDUCED_RATE THEN
        CASE
            WHEN gbi.WITHHOLD_TAX_CODE = 0 THEN 3
            WHEN gbi.WITHHOLD_TAX_CODE BETWEEN 1 AND 19 THEN 4
        END
        ELSE 5
    END
END);

给出以下结果:

现在,UPDATE SQL 需要大约 6 分钟以上。

以下是 tables 上的索引:

VENDOR列都是varchar(25)类型。

-- 编辑:(下面描述整个 table 结构):

SHOW CREATE TABLE GBI;

CREATE TABLE `GBI` (
  `VENDOR` varchar(25) CHARACTER SET utf8 NOT NULL,
  `COMPANY_CODE` varchar(5) CHARACTER SET latin1 NOT NULL DEFAULT '',
  `VENDOR_NAME` varchar(100) CHARACTER SET utf8 NOT NULL DEFAULT '',
  `WITHHOLD_TAX_TYPE` varchar(2) CHARACTER SET latin1 NOT NULL DEFAULT '',
  `WITHHOLD_TAX_CODE` varchar(2) CHARACTER SET latin1 NOT NULL DEFAULT '',
  `DOCUMENT_CURRENCY` varchar(4) CHARACTER SET latin1 NOT NULL DEFAULT '',
  `CREATE_DT` datetime NOT NULL,
  PRIMARY KEY (`VENDOR`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

SHOW CREATE TABLE VF_KRED;

CREATE TABLE `VF_KRED` (
  `VENDOR` varchar(25) CHARACTER SET latin1 NOT NULL,
  `COUNTRY_CODE` varchar(5) CHARACTER SET latin1 DEFAULT NULL,
  `COUNTRY` varchar(3) CHARACTER SET latin1 DEFAULT NULL,
  `SEARCH_TERM` varchar(100) CHARACTER SET latin1 DEFAULT NULL,
  `CREATE_DT` datetime DEFAULT NULL,
  `GBI_VAL_REP` int(11) NOT NULL DEFAULT 5,
  PRIMARY KEY (`VENDOR`),
  KEY `vf_kred` (`GBI_VAL_REP`),
  KEY `VF_KRED_COUNTRY_IDX` (`COUNTRY`) USING BTREE,
  CONSTRAINT `vf_kred_ibfk_1` FOREIGN KEY (`GBI_VAL_REP`) REFERENCES `VENDOR_RATE_CATEGORY` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

SHOW CREATE TABLE MASTER_DATA;

CREATE TABLE `MASTER_DATA` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `VENDOR_CODE` varchar(25) CHARACTER SET latin1 DEFAULT NULL,
  `VENDOR_NAME` varchar(2000) CHARACTER SET latin1 DEFAULT NULL,
  `COUNTRY` varchar(2) CHARACTER SET latin1 DEFAULT NULL,
  `APPLN_RECEIVED_FROM_US` datetime DEFAULT NULL,
  `ITUNES_CONTRACT_NUM` varchar(2000) CHARACTER SET latin1 DEFAULT NULL,
  `CONTRACT_EFFECTIVE_DT` datetime DEFAULT NULL,
  `CONTRACT_EXPIRATION_DT` datetime DEFAULT NULL,
  `AUTO_RENEWAL` varchar(10) CHARACTER SET latin1 DEFAULT NULL,
  `REDUCED_RATE` int(11) DEFAULT NULL,
  `FORM_17` varchar(45) CHARACTER SET latin1 DEFAULT NULL,
  `RESIDENCY_CERT_ISSUE_DT` datetime DEFAULT NULL,
  `TAX_AUTHORITY_SUBMISSION_DT` datetime DEFAULT NULL,
  `TAX_AUTHORITY_ACCEPTANCE_DT` datetime DEFAULT NULL,
  `STATUS` varchar(45) CHARACTER SET latin1 DEFAULT NULL,
  `FORM_17_EXPIRATION` varchar(45) CHARACTER SET latin1 DEFAULT NULL,
  `COMMENTS` varchar(2000) CHARACTER SET latin1 DEFAULT NULL,
  `REMARKS` varchar(2000) CHARACTER SET latin1 DEFAULT NULL,
  `CATEGORY` varchar(45) CHARACTER SET latin1 DEFAULT NULL,
  PRIMARY KEY (`ID`),
  KEY `MASTER_DATA_VENDOR_CODE_IDX` (`VENDOR_CODE`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2369 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

有什么线索吗?

不要在需要比较的列上混用 CHARACTER SETs(或数据类型或排序规则),如 JOIN。请注意 vendorlatin1utf8 的区别。这会减慢 JOIN。 (此外,检查 vendor_code 由于另一个连接。)

EXPLAIN中的线索:"func"。这意味着 vendor 以某种方式被修改以执行 JOINCREATE TABLE 表明字符集不同。

如果您只有 1GB 的 RAM,

128MB for innodb_buffer_pool_size 是合适的,甚至是可取的。对于 8GB,6G 会是一个更好的设置。通过增加该值,您可能会减少 I/O 此查询和其他查询所必需的 I/O。同样,这会影响 JOIN.

的速度