如何使 complex/long 运行 SQL 查询更有效率?
How can I make a complex/long running SQL query more efficient?
我创建了一个从多个 table 中检索数据的查询。当我 运行 它时,执行需要大约 200 秒。我现在正在尝试使查询更有效率,但我已达到我的极限并且无法找到解决方案。您是否知道我可以如何改进以下查询?
SELECT s1.otherdeed_id, s1.timestamp_start, s1.listingprice, s1.listing_currency, otherdeed_index.category, otherdeed_index.koda_id, kodas.mega, otherdeed_index.artifact_name, otherdeed_index.sediment
FROM otherdeed_opensea_listings s1
JOIN (
SELECT otherdeed_id, listingprice, MAX(timestamp_start) AS timestamp_start
FROM otherdeed_opensea_listings
GROUP BY otherdeed_id) AS s2
ON s1.otherdeed_id = s2.otherdeed_id AND s1.timestamp_start = s2.timestamp_start
INNER JOIN otherdeed_index ON otherdeed_index.id_otherdeed = s1.otherdeed_id
INNER JOIN kodas ON otherdeed_index.koda_id = kodas.kodaname
ORDER BY otherdeed_id;
查询应提供 otherdeed_opensea_listings table(16k条目)并将其与 tables otherdeed_index(100k 条目)和 kodas (10k 条目) 获取一些相关数据进行分析。
我将 otherdeed_opensea_listings table 分组,每个 只得到一个结果otherdeedid,此外,只获取最高 timestamp_start[=38= 的最新结果也很重要]值。
下面你可以看到我的sql结构:
CREATE TABLE `kodas` (
`kodaid` int(11) NOT NULL AUTO_INCREMENT,
`kodaname` int(11) NOT NULL,
`image` varchar(255) NOT NULL,
`mega` tinyint(1) NOT NULL,
`clothing` varchar(100) NOT NULL,
`core` varchar(100) NOT NULL,
`eyes` varchar(100) NOT NULL,
`head` varchar(100) NOT NULL,
`weapon` varchar(100) NOT NULL,
PRIMARY KEY (`kodaid`)
) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8
CREATE TABLE `otherdeed_index` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_otherdeed` int(11) NOT NULL,
`plot` int(11) NOT NULL,
`image` varchar(200) NOT NULL,
`category` varchar(20) NOT NULL,
`sediment` varchar(40) NOT NULL,
`sediment_tier` tinyint(1) NOT NULL,
`environment` varchar(50) NOT NULL,
`environment_tier` tinyint(1) NOT NULL,
`artifact_name` varchar(80) NOT NULL,
`r_east` varchar(20) NOT NULL,
`r_west` varchar(20) NOT NULL,
`r_south` varchar(20) NOT NULL,
`r_north` varchar(20) NOT NULL,
`r_east_tier` tinyint(1) NOT NULL,
`r_west_tier` tinyint(1) NOT NULL,
`r_south_tier` tinyint(1) NOT NULL,
`r_north_tier` tinyint(1) NOT NULL,
`koda_id` int(6) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=115001 DEFAULT CHARSET=utf8
CREATE TABLE `otherdeed_opensea_listings` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`eventid` bigint(20) NOT NULL,
`event_type` varchar(10) NOT NULL,
`auction_type` varchar(10) NOT NULL,
`otherdeed_id` int(9) NOT NULL,
`timestamp_created` int(11) NOT NULL,
`timestamp_start` int(11) NOT NULL,
`timestamp_end` int(11) NOT NULL,
`duration_active` int(11) NOT NULL,
`listingprice` float NOT NULL,
`listing_currency` varchar(20) NOT NULL,
`status` tinyint(1) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=418927 DEFAULT CHARSET=utf8
我的 sql 查询的输出:(解释 select)
您肯定需要一些索引。尝试添加以下内容:
ALTER TABLE otherdeed_opensea_listings
ADD INDEX timestamp_start (timestamp_start),
ADD INDEX otherdeed_id (otherdeed_id);
ALTER TABLE otherdeed_index
ADD INDEX id_otherdeed (id_otherdeed),
ADD INDEX koda_id (koda_id);
ALTER TABLE kodas
ADD INDEX kodaname (kodaname);
这可能会给您更快的结果。这是 fiddle test with explain.
我创建了一个从多个 table 中检索数据的查询。当我 运行 它时,执行需要大约 200 秒。我现在正在尝试使查询更有效率,但我已达到我的极限并且无法找到解决方案。您是否知道我可以如何改进以下查询?
SELECT s1.otherdeed_id, s1.timestamp_start, s1.listingprice, s1.listing_currency, otherdeed_index.category, otherdeed_index.koda_id, kodas.mega, otherdeed_index.artifact_name, otherdeed_index.sediment
FROM otherdeed_opensea_listings s1
JOIN (
SELECT otherdeed_id, listingprice, MAX(timestamp_start) AS timestamp_start
FROM otherdeed_opensea_listings
GROUP BY otherdeed_id) AS s2
ON s1.otherdeed_id = s2.otherdeed_id AND s1.timestamp_start = s2.timestamp_start
INNER JOIN otherdeed_index ON otherdeed_index.id_otherdeed = s1.otherdeed_id
INNER JOIN kodas ON otherdeed_index.koda_id = kodas.kodaname
ORDER BY otherdeed_id;
查询应提供 otherdeed_opensea_listings table(16k条目)并将其与 tables otherdeed_index(100k 条目)和 kodas (10k 条目) 获取一些相关数据进行分析。
我将 otherdeed_opensea_listings table 分组,每个 只得到一个结果otherdeedid,此外,只获取最高 timestamp_start[=38= 的最新结果也很重要]值。
下面你可以看到我的sql结构:
CREATE TABLE `kodas` (
`kodaid` int(11) NOT NULL AUTO_INCREMENT,
`kodaname` int(11) NOT NULL,
`image` varchar(255) NOT NULL,
`mega` tinyint(1) NOT NULL,
`clothing` varchar(100) NOT NULL,
`core` varchar(100) NOT NULL,
`eyes` varchar(100) NOT NULL,
`head` varchar(100) NOT NULL,
`weapon` varchar(100) NOT NULL,
PRIMARY KEY (`kodaid`)
) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8
CREATE TABLE `otherdeed_index` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_otherdeed` int(11) NOT NULL,
`plot` int(11) NOT NULL,
`image` varchar(200) NOT NULL,
`category` varchar(20) NOT NULL,
`sediment` varchar(40) NOT NULL,
`sediment_tier` tinyint(1) NOT NULL,
`environment` varchar(50) NOT NULL,
`environment_tier` tinyint(1) NOT NULL,
`artifact_name` varchar(80) NOT NULL,
`r_east` varchar(20) NOT NULL,
`r_west` varchar(20) NOT NULL,
`r_south` varchar(20) NOT NULL,
`r_north` varchar(20) NOT NULL,
`r_east_tier` tinyint(1) NOT NULL,
`r_west_tier` tinyint(1) NOT NULL,
`r_south_tier` tinyint(1) NOT NULL,
`r_north_tier` tinyint(1) NOT NULL,
`koda_id` int(6) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=115001 DEFAULT CHARSET=utf8
CREATE TABLE `otherdeed_opensea_listings` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`eventid` bigint(20) NOT NULL,
`event_type` varchar(10) NOT NULL,
`auction_type` varchar(10) NOT NULL,
`otherdeed_id` int(9) NOT NULL,
`timestamp_created` int(11) NOT NULL,
`timestamp_start` int(11) NOT NULL,
`timestamp_end` int(11) NOT NULL,
`duration_active` int(11) NOT NULL,
`listingprice` float NOT NULL,
`listing_currency` varchar(20) NOT NULL,
`status` tinyint(1) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=418927 DEFAULT CHARSET=utf8
我的 sql 查询的输出:(解释 select)
您肯定需要一些索引。尝试添加以下内容:
ALTER TABLE otherdeed_opensea_listings
ADD INDEX timestamp_start (timestamp_start),
ADD INDEX otherdeed_id (otherdeed_id);
ALTER TABLE otherdeed_index
ADD INDEX id_otherdeed (id_otherdeed),
ADD INDEX koda_id (koda_id);
ALTER TABLE kodas
ADD INDEX kodaname (kodaname);
这可能会给您更快的结果。这是 fiddle test with explain.