用更快的东西替换join

vddsk6oq  于 2021-06-17  发布在  Mysql
关注(0)|答案(2)|浏览(284)

**结束。**此问题需要详细的调试信息。它目前不接受答案。
**想改进这个问题吗?**更新问题,使其成为堆栈溢出的主题。

两年前关门了。
改进这个问题
我在sql中有一个视图,它使用了一个连接,并且花费的时间比我希望的要长得多。我想如果我把它转换成子查询,它会运行得更快,但是我有问题。
基本上,我想创建一个“target”列来计算资产价格的24小时百分比变化。现在,我要做的是创建第一个视图,它是普通表,然后是第二个视图,它是第一个表的副本,但是日期是+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;

以下是查询输出的屏幕截图:
选择*from pricetarget,其中symbol='btc'order by date desc;
有没有想过如何用一个更快的查询来避免使用连接来获得相同的结果?
任何帮助都将不胜感激!
编辑:我想这只是归结为一个事实,我只是有很多数据正在加载。我创建了一个新的first视图来提前过滤我的数据,从而将加载时间从大约32秒减少到10秒多一点。感谢那些帮助过我的人!

ktecyv1j

ktecyv1j1#

我首先要对查询本身进行一些分析,找出造成瓶颈的原因,即如何调用表、每个表返回多少行、使用哪些索引等。在from子句中对表重新排序这样的简单操作可以提高性能。您的查询可能缺少一两个索引,这可能会大大提高性能。

4xy9mtcn

4xy9mtcn2#

在priceview2的创建过程中,似乎有一些不必要的代码
就像最后的order by一样,您计算price和btc,但不在pricetarget视图中使用它们(您使用priceview1中已经可用的值)。我认为你把它放在那里是为了有唯一的日期/符号,你可以用一个select distinct来实现相同的结果。
我不知道这是否是故意的,但btc和价格是根据pricesview1中的平均值计算的,而不是pricesview2中的平均值。
以下是我对价格视图2的建议:

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'

我对视图的理解是,它们可以与其他语言中的宏相比较:更像是代码替换,而不是预计算。
所以,当你在pricetarget avg(pv1.price)中这样做时,考虑到pv1.price被定义为avg(price),你是平均值。
除了上面我建议的修改之外,我还修改了pricesview2来计算新的价格和btc平均值,这样pricetarget视图就不必这样做了
最后,在pricetarget视图中,除了pv1.date和pv1.symbol之外,还应该按pv1.pkey分组。

相关问题