MySQL 一些查询永远不会执行
MySQL some queries never exectue
我正在进行我的第一个数据科学项目,我在使用 MySQL Workbench 进行极其缓慢的查询时遇到了一些麻烦。
这是我的3个table(每个都来自各个网站的数据集,已经清理并插入MySQL):
CREATE TABLE IF NOT EXISTS `starbucks` (
`STORE_NUMBER` varchar(20) NOT NULL,
`CITY` varchar(50) NOT NULL,
`STATE` char(2) NOT NULL,
`ZIPCODE` char(5) NOT NULL,
`LONG` varchar(10) NOT NULL,
`LAT` varchar(10) NOT NULL,
PRIMARY KEY (`STORE_NUMBER`)
)ENGINE=InnoDB")
CREATE TABLE IF NOT EXISTS `income`(
`STATEFIPS` char(2) NOT NULL,
`STATE` char(2) NOT NULL,
`ZIPCODE` char(5) NOT NULL,
`AGI_STUB` tinyint NOT NULL,
`NUM_RETURNS` float(15,4) NOT NULL,
`TOTAL_INCOME` float(15,4) NOT NULL,
PRIMARY KEY (`STATE`, `ZIPCODE`, `AGI_STUB`)
)ENGINE=InnoDB")
CREATE TABLE IF NOT EXISTS `diversity`(
`COUNTY` varchar(50) NOT NULL,
`STATE` char(2) NOT NULL,
`INDEX` float(7,6) NOT NULL,
`1` float(3,1) NOT NULL,
`2` float(3,1) NOT NULL,
`3` float(3,1) NOT NULL,
`4` float(3,1) NOT NULL,
`5` float(3,1) NOT NULL,
`6` float(3,1) NOT NULL,
`7` float(3,1) NOT NULL,
PRIMARY KEY (`COUNTY`, `STATE`)
)ENGINE=InnoDB")
starbucks
有 13,608 条记录,
income
有 166,740 条记录,
diversity
有 3,143 条记录。
我正在尝试的查询 运行:
SELECT i.TOTAL_INCOME,
CASE
WHEN s.STORE_NUMBER IS NOT NULL THEN 1
ELSE 0
END AS has_starbucks
FROM income as i
LEFT OUTER JOIN starbucks as s
ON i.ZIPCODE = s.ZIPCODE
如果我将结果限制为 1,000 行,它会 运行 很快,但是我需要获取所有记录(没有行限制),这会导致查询永远不会返回,并最终超时并断开我与 MySQL 服务器的连接。
过去,在为拥有数百万条记录的数据库工作时,我从来没有遇到过这么多麻烦。
我需要做什么 table 优化来解决这个问题?我需要更改哪些 MySQL 设置?欢迎任何其他建议。
编辑
查询的 'Duration' 似乎永远不会超过 0.500 秒,'Fetch' 部分持续 > 120 秒。我不确定这是否有用。
第一个问题是在连接列上创建适当的索引
CREATE INDEX idx1 ON starbucks (ZIPCODE );
CREATE INDEX idx2 ON income (ZIPCODE );
或添加您 select
列的冗长索引
CREATE INDEX idx2 ON income (ZIPCODE , TOTAL_INCOME);
并使用解释计划检查行为
这对解决性能问题没有太大作用,但会解决重复行问题 -
SELECT i.TOTAL_INCOME, 1 AS has_starbucks
FROM income as i
WHERE i.Zipcode in (Select zipcode from Starbucks)
UNION
SELECT i.TOTAL_INCOME, 0 AS has_starbucks
FROM income as i
WHERE i.Zipcode not in (Select zipcode from Starbucks)
EXISTS 有时比 IN
更有效
SELECT i.TOTAL_INCOME, 1 AS has_starbucks
FROM income as i
WHERE EXISTS
( SELECT 1
FROM Starbucks s
WHERE s.zipcode = i.Zipcode
)
UNION
SELECT i.TOTAL_INCOME, 0 AS has_starbucks
FROM income as i
WHERE NOT EXISTS
( SELECT 1
FROM Starbucks s
WHERE s.zipcode = i.Zipcode
)
我正在进行我的第一个数据科学项目,我在使用 MySQL Workbench 进行极其缓慢的查询时遇到了一些麻烦。
这是我的3个table(每个都来自各个网站的数据集,已经清理并插入MySQL):
CREATE TABLE IF NOT EXISTS `starbucks` (
`STORE_NUMBER` varchar(20) NOT NULL,
`CITY` varchar(50) NOT NULL,
`STATE` char(2) NOT NULL,
`ZIPCODE` char(5) NOT NULL,
`LONG` varchar(10) NOT NULL,
`LAT` varchar(10) NOT NULL,
PRIMARY KEY (`STORE_NUMBER`)
)ENGINE=InnoDB")
CREATE TABLE IF NOT EXISTS `income`(
`STATEFIPS` char(2) NOT NULL,
`STATE` char(2) NOT NULL,
`ZIPCODE` char(5) NOT NULL,
`AGI_STUB` tinyint NOT NULL,
`NUM_RETURNS` float(15,4) NOT NULL,
`TOTAL_INCOME` float(15,4) NOT NULL,
PRIMARY KEY (`STATE`, `ZIPCODE`, `AGI_STUB`)
)ENGINE=InnoDB")
CREATE TABLE IF NOT EXISTS `diversity`(
`COUNTY` varchar(50) NOT NULL,
`STATE` char(2) NOT NULL,
`INDEX` float(7,6) NOT NULL,
`1` float(3,1) NOT NULL,
`2` float(3,1) NOT NULL,
`3` float(3,1) NOT NULL,
`4` float(3,1) NOT NULL,
`5` float(3,1) NOT NULL,
`6` float(3,1) NOT NULL,
`7` float(3,1) NOT NULL,
PRIMARY KEY (`COUNTY`, `STATE`)
)ENGINE=InnoDB")
starbucks
有 13,608 条记录,
income
有 166,740 条记录,
diversity
有 3,143 条记录。
我正在尝试的查询 运行:
SELECT i.TOTAL_INCOME,
CASE
WHEN s.STORE_NUMBER IS NOT NULL THEN 1
ELSE 0
END AS has_starbucks
FROM income as i
LEFT OUTER JOIN starbucks as s
ON i.ZIPCODE = s.ZIPCODE
如果我将结果限制为 1,000 行,它会 运行 很快,但是我需要获取所有记录(没有行限制),这会导致查询永远不会返回,并最终超时并断开我与 MySQL 服务器的连接。 过去,在为拥有数百万条记录的数据库工作时,我从来没有遇到过这么多麻烦。
我需要做什么 table 优化来解决这个问题?我需要更改哪些 MySQL 设置?欢迎任何其他建议。
编辑 查询的 'Duration' 似乎永远不会超过 0.500 秒,'Fetch' 部分持续 > 120 秒。我不确定这是否有用。
第一个问题是在连接列上创建适当的索引
CREATE INDEX idx1 ON starbucks (ZIPCODE );
CREATE INDEX idx2 ON income (ZIPCODE );
或添加您 select
列的冗长索引CREATE INDEX idx2 ON income (ZIPCODE , TOTAL_INCOME);
并使用解释计划检查行为
这对解决性能问题没有太大作用,但会解决重复行问题 -
SELECT i.TOTAL_INCOME, 1 AS has_starbucks
FROM income as i
WHERE i.Zipcode in (Select zipcode from Starbucks)
UNION
SELECT i.TOTAL_INCOME, 0 AS has_starbucks
FROM income as i
WHERE i.Zipcode not in (Select zipcode from Starbucks)
EXISTS 有时比 IN
更有效 SELECT i.TOTAL_INCOME, 1 AS has_starbucks
FROM income as i
WHERE EXISTS
( SELECT 1
FROM Starbucks s
WHERE s.zipcode = i.Zipcode
)
UNION
SELECT i.TOTAL_INCOME, 0 AS has_starbucks
FROM income as i
WHERE NOT EXISTS
( SELECT 1
FROM Starbucks s
WHERE s.zipcode = i.Zipcode
)