mysql - SQL 用更快的东西替换连接

标签 mysql sql join subquery mysql-workbench

<分区>

我在 SQL 中有一个使用连接的 View ,它花费的时间比我希望的要长得多。我认为如果我将它转换为子查询它会运行得更快,但我遇到了麻烦。

基本上,我想创建一个“目标”列来计算 Assets 价格 24 小时的百分比变化。现在,我的方法是创建第一个 View ,它是普通表,然后是第二个 View ,它是第一个表的副本,但带有 date+1,然后我可以用它来计算 24 小时目标。下面是我的sql代码。我在 MySQL 工作。

create view PricesView1 as
select Date,Symbol, avg(Price) as 'Price', avg(BTC_Dominance) as 'BTC_Dominance', 
    pkdummy,pkey from Prices group by Date,pkdummy,pkey, Symbol 
    having right(pkdummy,2)=22 and Date > '2018-11-22';

create view PricesView2 as
select sq.Date, sq.oldDate, sq.Symbol, sq.Price, newP.Price as 'NewPrice',
    newP.BTC_Dominance as 'NewBTCdominance', newP.pkdummy from (
    select date_add(Date, INTERVAL 1 DAY) as 'Date', Date as 'oldDate',Symbol,avg(Price) as 'Price', 
        avg(BTC_Dominance) as 'BTC_Dominance',  pkdummy,pkey from Prices 
        group by Date,date_add(Date, INTERVAL 1 DAY),pkdummy,pkey, Symbol having right(pkdummy,2)=22)sq
    join Prices newP on newP.Date=sq.Date and newP.Symbol=sq.Symbol 
    where right(newP.pkdummy,2)=22 and sq.Date > '2018-11-22' order by datetime desc;

#Use other two views to calculate target
create view priceTarget as
select pv1.Date, pv1.Symbol, avg(pv1.Price) as 'Initial Price', avg(pv2.NewPrice) as 'Price24hLater',
    avg(((pv2.NewPrice-pv1.Price)/pv1.Price)*100) as 'Target24hChange',
    avg(((pv2.NewBTCdominance-pv1.BTC_Dominance)/pv1.BTC_Dominance)*100) as 'BTCdominance24hChange',
    pv1.pkey from PricesView1 pv1 
    join PricesView2 pv2 on pv1.Date=pv2.oldDate and pv1.Symbol=pv2.Symbol
    group by pv1.Date, pv1.Symbol;

Here is a screenshot of the output of the query:
SELECT * FROM priceTarget WHERE symbol = 'btc' ORDER BY date desc;

关于如何通过避免使用连接的更快查询获得相同结果的任何想法?

非常感谢任何帮助!


编辑:我想这只是归结为我只是加载了大量数据这一事实。我创建了一个新的第一个 View 来提前过滤我的数据,并将加载时间从大约 32 秒减少到略高于 10 秒。感谢那些提供帮助的人!

最佳答案

在PriceView2的创建中似乎有一些不必要的代码

就像最后的订单一样,您计算价格和 BTC,但不要在 priceTarget View 中使用它们(您使用 PriceView1 中已经可用的值)。我想你把它留在那里是为了拥有独特的日期/符号,你可以使用 select DISTINCT 来获得相同的结果。

我不知道这是不是故意的,但 BTC 和价格是根据 PricesView1 中的平均值计算的,而不是在 PricesView2 中。

这是我对 PricesView2 的建议:

create view PricesView2 as
select
    sq.Date,
    newP.Date,
    sq.Symbol,
    newP.Price as 'NewPrice',
    newP.BTC_Dominance as 'NewBTCdominance',
    newP.pkdummy
from (
        select distinct
            Date as 'oldDate',
            Symbol,
            pkdummy,
            pkey
        from Prices 
        having right(pkdummy,2)=22) sq
    join Prices newP on
        newP.Date=date_add(sq.oldDate, INTERVAL 1 DAY)
        and newP.Symbol=sq.Symbol 
where right(newP.pkdummy,2)=22
and   sq.Date > '2018-11-22'

我对 View 的理解是它们类似于其他语言中的宏:更像是代码替换而不是预计算。

因此,当您在 priceTarget avg(pv1.Price) 中执行操作时,考虑到 pv1.Price 被定义为 avg(Price),您计算的是平均值。

除了我上面建议的更改之外,我还会更改 PricesView2 以计算新价格和 BTC 平均值,这样 priceTarget View 就不必了

最后,在您的 priceTarget View 中,除了 pv1.Date 和 pv1.symbol 之外,您还应该按 pv1.pkey 分组。

关于mysql - SQL 用更快的东西替换连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53756799/

相关文章:

sql - 如何根据不同的 WHERE 选择一列并生成两个不同的列

sql - LISTAGG函数: "result of string concatenation is too long"

php - 为什么当我向 mysqli_query 发送多个查询时会出现错误?

php - Codeigniter 多对多错误

mysql - 无论如何要在 mysql 的行中附加列数据?

php - 将辅助数据输入预先存在的数据库

php - 使用 Sphinx 搜索进行“最佳匹配”人名搜索/排名

c# - 如何加快从Mysql数据库中检索数据的速度

php - 删除孤立记录 - mysql

MySql LEFT OUTER JOIN 导致重复行