我的500000
中有MySQL server
个记录表。运行查询时,查询将花费更多时间。有时会超过一分钟。
下面,我添加了我的MySQL机器详细信息。
RAM-16GB
处理器:Intel®Core™i5-4460M CPU @ 3.20GHz
操作系统:Windows服务器64位
我知道我的机器没有问题,因为它是一台独立的机器,并且那里没有其他应用程序。
也许我的查询有问题。我浏览了MySql网站,发现我使用了正确的语法。但是我不确切知道延迟结果的原因。
SELECT SUM(`samplesalesdata50000`.`UnitPrice`) AS `UnitPrice`, `samplesalesdata50000`.`SalesChannel` AS `Channel`
FROM `samplesalesdata50000` AS `samplesalesdata50000`
GROUP BY `samplesalesdata50000`.`SalesChannel`
ORDER BY 2 ASC
LIMIT 200 OFFSET 0
任何人都可以让我知道持续时间是否取决于我使用的表还是查询?
注意:即使尝试使用索引,结果时间也没有太大差异。
谢谢
答案 0 :(得分:2)
两种方法:
一种方法是在满足查询所需的列上创建a covering index。您查询的正确索引按以下顺序包含这些列:(SalesChannel, UnitPrice)
。
为什么有帮助?一方面,索引本身包含满足查询所需的所有数据,而没有别的。这意味着您的服务器工作量更少。
另一方面,MySQL的索引是BTREE组织的。这意味着它们可以按顺序访问。因此您的查询可以一次满足一个SalesChannel
,并且MySQL不需要内部临时表。这样更快。
第二种方法涉及到认识到ORDER BY ... LIMIT
是一个臭名昭著的性能反模式。您需要MySQL对大量数据进行排序,然后丢弃其中的大部分数据。
您可以尝试以下方法:
SELECT SUM(UnitPrice) UnitPrice,
SalesChannel Channel
FROM samplesalesdata50000
WHERE SalesChannel IN (
SELECT SalesChannel
FROM samplesalesdata50000
ORDER BY Channel LIMIT 200 OFFSET 0
)
GROUP BY SalesChannel
ORDER BY SalesChannel
LIMIT 200 OFFSET 0
如果您在SalesChannel
上有一个索引(上面提到的覆盖索引有效),这应该可以大大提高您的速度,因为您的汇总(GROUP BY
)查询只需要考虑表的一个子集。
答案 1 :(得分:0)
您的“ ORDER BY 2 ASC”问题。试试这个“按频道订购”。
答案 2 :(得分:0)
如果是MS SQL Server,则可以使用WITH (NOLOCK)
与MYSQL等效的是
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT SUM(`samplesalesdata50000`.`UnitPrice`) AS `UnitPrice`, `samplesalesdata50000`.`SalesChannel` AS `Channel`
FROM `samplesalesdata50000` AS `samplesalesdata50000`
GROUP BY `samplesalesdata50000`.`SalesChannel`
ORDER BY SalesChannel ASC
LIMIT 200 OFFSET 0
COMMIT ;
答案 3 :(得分:0)
要改善OJones的答案,请注意
df1 <- read.table(unz(temp, "Products.txt"), sep="\t", quote = "\"", fill = TRUE,
comment.char = "", header= TRUE)
df2 <- read.delim(unz(temp, "Products.txt"), sep="\t", header= TRUE)
all.equal(df1, df2)
# [1] TRUE
identical(df1, df2)
# [1] TRUE
将迅速(假定给定索引)找到所需列表的末尾。然后添加此选项将主查询限制为仅需要的行:
SELECT SalesChannel FROM samplesalesdata50000
ORDER BY SalesChannel LIMIT 200, 1
但是,这是一个问题。如果表中的行数少于200,则子查询将不返回任何内容。
您似乎要设置“分页”?在这种情况下,可以使用类似的技术来查找起始值:
WHERE SalesChannel < (that-select)
这也避免了使用效率低下的WHERE SalesChannel >= ...
AND SalesChannel < ...
,后者必须先读取然后折腾所有跳过的行。 More
但是真正的解决方案可能是建立和维护数据汇总表。它将包含每个月的小计。然后针对“摘要”表运行查询-可能会快10倍。 More