您好,我的一个请求很慢,时间很长。 我测试使用 INDEX,没有结果。 我被建议放置内部连接而不是我的选择,但我不知道如何在同一张表上进行不同的操作。
表格:
CREATE TABLE `cryptos` (
`uuid` char(36) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`shortname` varchar(255) DEFAULT NULL,
[...]
`createdAt` datetime NOT NULL,
`updatedAt` datetime NOT NULL,
PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `cryptos_infos` (
`id` int(11) NOT NULL AUTO_INCREMENT,
[...]
`createdAt` datetime NOT NULL,
`updatedAt` datetime NOT NULL,
`fk_cryptoid` char(36) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_cryptoid` (`fk_cryptoid`),
CONSTRAINT `cryptos_infos_ibfk_1` FOREIGN KEY (`fk_cryptoid`) REFERENCES `cryptos` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `eventcryptorelations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
[...]
`fk_cryptoid` char(36) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
`fk_eventid` char(36) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_cryptoid` (`fk_cryptoid`),
KEY `fk_eventid` (`fk_eventid`),
CONSTRAINT `eventcryptorelations_ibfk_1` FOREIGN KEY (`fk_cryptoid`) REFERENCES `cryptos` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `eventcryptorelations_ibfk_2` FOREIGN KEY (`fk_eventid`) REFERENCES `events` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `events` (
`uuid` char(36) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`title` varchar(255) DEFAULT NULL,
[...]
PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `github_activ_repos` (
`id` int(11) NOT NULL AUTO_INCREMENT,
[...]
`fk_githubid` char(36) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_githubid` (`fk_githubid`),
CONSTRAINT `github_activ_repos_ibfk_1` FOREIGN KEY (`fk_githubid`) REFERENCES `github_info_repos` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `github_info_repos` (
`uuid` char(36) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`idgit` int(11) DEFAULT NULL,
[...]
`fk_cryptoid` char(36) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
PRIMARY KEY (`uuid`),
KEY `fk_cryptoid` (`fk_cryptoid`),
CONSTRAINT `github_info_repos_ibfk_1` FOREIGN KEY (`fk_cryptoid`) REFERENCES `cryptos` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `prices` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`open` double DEFAULT NULL,
[...]
`date` datetime DEFAULT NULL,
`createdAt` datetime NOT NULL,
`updatedAt` datetime NOT NULL,
`fk_cryptoid` char(36) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_cryptoid` (`fk_cryptoid`),
CONSTRAINT `prices_ibfk_1` FOREIGN KEY (`fk_cryptoid`) REFERENCES `cryptos` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `trendsSearches` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`time` datetime DEFAULT NULL,
`formattedTime` varchar(255) DEFAULT NULL,
`value` float DEFAULT NULL,
`createdAt` datetime NOT NULL,
`updatedAt` datetime NOT NULL,
`fk_cryptoid` char(36) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_cryptoid` (`fk_cryptoid`),
CONSTRAINT `trendsSearches_ibfk_1` FOREIGN KEY (`fk_cryptoid`) REFERENCES `cryptos` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `twitter_activs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
[...]
`fk_twitterid` double DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_twitterid` (`fk_twitterid`),
CONSTRAINT `twitter_activs_ibfk_1` FOREIGN KEY (`fk_twitterid`) REFERENCES `twitter_infos` (`idtwitter`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `twitter_infos` (
`idtwitter` double NOT NULL,
[...]
`fk_cryptoid` char(36) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
PRIMARY KEY (`idtwitter`),
KEY `fk_cryptoid` (`fk_cryptoid`),
CONSTRAINT `twitter_infos_ibfk_1` FOREIGN KEY (`fk_cryptoid`) REFERENCES `cryptos` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `volumes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`volumefrom` double DEFAULT NULL,
[...]
`fk_cryptoid` char(36) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fk_cryptoid` (`fk_cryptoid`),
CONSTRAINT `volumes_ibfk_1` FOREIGN KEY (`fk_cryptoid`) REFERENCES `cryptos` (`uuid`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
为了更好地理解,我缩小了表格。
查询说明:
我需要按 cryptos_info 表中的“排名”字段排序前 100 个条目。 以最新入场价和24小时前的价格。 与其他表上的其他信息,例如卷上的条目,在表 github ....
查询:
select cryptos_infos.rank, cryptos.shortname, cryptos.imageurl, cryptos_infos.coinminde,
(SELECT open FROM prices WHERE prices.fk_cryptoid = cryptos.uuid and prices.date LIKE '2018-09-16%' order by prices.date DESC limit 1) as priceone,
(SELECT open FROM prices WHERE prices.fk_cryptoid = cryptos.uuid and prices.date LIKE '2018-09-16%' order by prices.date DESC limit 1) as pricetwo ,
(SELECT P.open FROM prices P WHERE P.fk_cryptoid = cryptos.uuid order by P.createdAt DESC limit 1) as open,
(select count(E.hot) from events E where E.uuid in (select EC.fk_eventid from eventcryptorelations EC where EC.fk_cryptoid = cryptos.uuid) and E.hot = 1) as hot,
(SELECT value FROM trendsSearches WHERE trendsSearches.fk_cryptoid = cryptos.uuid order by trendsSearches.time DESC limit 1) as trenone,
(SELECT value FROM trendsSearches WHERE trendsSearches.fk_cryptoid = cryptos.uuid order by trendsSearches.time DESC LIMIT 1,1) as trentwo,
(select GAR.stars from github_activ_repos GAR where GAR.fk_githubid = ( select uuid from github_info_repos GIR, github_activ_repos GR where GIR.fk_cryptoid = cryptos.uuid and GIR.uuid = GR.fk_githubid order by GR.stars DESC limit 1) order by GAR.time DESC limit 1) as gitone,
(select GAR.stars from github_activ_repos GAR where GAR.fk_githubid = ( select uuid from github_info_repos GIR, github_activ_repos GR where GIR.fk_cryptoid = cryptos.uuid and GIR.uuid = GR.fk_githubid order by GR.stars DESC limit 1) order by GAR.time DESC limit 1,1) as gittwo,
(SELECT abonnees FROM twitter_activs WHERE twitter_activs.fk_twitterid = (select idtwitter from twitter_infos where twitter_infos.fk_cryptoid = cryptos.uuid) and twitter_activs.createdAt LIKE '2018-09-16%' order by twitter_activs.createdAt DESC limit 1) as abotone,
(SELECT abonnees FROM twitter_activs WHERE twitter_activs.fk_twitterid = (select idtwitter from twitter_infos where twitter_infos.fk_cryptoid = cryptos.uuid) and twitter_activs.createdAt LIKE '2018-09-16%' order by twitter_activs.createdAt DESC limit 1) as abottwo
from cryptos, cryptos_infos where cryptos.uuid = cryptos_infos.fk_cryptoid and cryptos_infos.rank is not null order by cryptos_infos.rank ASC limit 100;
信息: 所有请求 = 30s
请求 - 选择表格价格 = 1.23s
出现慢问题的线路:
(SELECT open FROM prices WHERE prices.fk_cryptoid = cryptos.uuid and prices.date LIKE '2018-09-23%' order by prices.date DESC limit 1) as priceone,
(SELECT open FROM prices WHERE prices.fk_cryptoid = cryptos.uuid and prices.date LIKE '2018-09-23%' order by prices.date DESC limit 1) as pricetwo ,
(SELECT P.open FROM prices P WHERE P.fk_cryptoid = cryptos.uuid order by P.createdAt DESC limit 1) as open,
最佳答案
首先,不要对日期使用like
。相反:
(SELECT open FROM prices p WHERE p.fk_cryptoid = cryptos.uuid and p.date >= '2018-09-23' AND p.date < '2018-09-24' order by p.date DESC limit 1) as priceone,
(SELECT open FROM prices p WHERE p.fk_cryptoid = cryptos.uuid and p.date >= '2018-09-23' AND p.date < '2018-09-24' order by p.date DESC limit 1) as pricetwo ,
(SELECT P.open FROM prices P WHERE P.fk_cryptoid = cryptos.uuid order by P.createdAt DESC limit 1) as open,
为此,您可以尝试在 prices(fk_cryptoid, p.date, open)
和 prices(fk_cryptoid, createdAt, open)
上建立索引。
你可能需要更激烈一点。目标是为子查询使用索引。我不确定 MySQL 是否足够聪明,可以在这些情况下做到这一点。
您可能需要将现有的 date
列更改为只是一个日期,并添加一个包含日期/时间(或只是一个时间列)的新日期时间列。然后您可以将子查询表述为:
(SELECT open FROM prices p WHERE p.fk_cryptoid = cryptos.uuid and p.date = '2018-09-23' order by p.datetime DESC limit 1) as priceone,
你想要的索引在 (fk_cryptoid, date, datetime, open)
上。
关于mysql - SQL 查询优化 select 或 inner join,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52466280/