sql优化:通过子查询或自己的查询/其他改进计算所有行

jucafojl  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(314)

我正在努力改进mysql查询。首先,我试图优化这个简单的:

SELECT * , 
    (
        SELECT COUNT(id)
            FROM animal 
            WHERE type = :type  AND timestampadopt > 0 AND (date BETWEEN  DATE_FORMAT(CURDATE() , '%Y-%m-%d') - INTERVAL 1 YEAR AND DATE_FORMAT(CURDATE(),'%Y-%m-%d'))          
            ) AS countanimals
        FROM animal
        WHERE type = :type  AND timestampadopt > 0 AND (date BETWEEN  DATE_FORMAT(CURDATE() , '%Y-%m-%d') - INTERVAL 1 YEAR AND DATE_FORMAT(CURDATE(),'%Y-%m-%d'))
        ORDER BY timestamp DESC
        LIMIT 1, 20;

柱:

id | timestampadd | timestampadopt | dateborn | animaltype | gender | chipped | smalldescger | smalldesceng | imagepath

在那个受影响的地方,我把所有的动物圈起来,分页。所以你可以看到20只动物,接下来的20只你必须使用“下一步”按钮。
我需要知道分页需要显示多少个站点,所以我必须计算总共有多少个动物,这就是子查询所做的。
我对时间进行了测量,得到了以下结果:
总查询为0.0047s,
子查询为0.0023s
数据库中只有5行!
在那个网站上,我提供了一些过滤器,如年龄+/-1岁,是动物已经被采纳,因为我需要在这两个地方的条款,这可能占了最多的性能,其次是顺序条款,这是必要的,以显示新的第一。
p、 我需要表中的所有列,我做了一些测试 SELECT * 有相同的运行时,然后像一些人推荐的那样手动选择所有10列。
编辑:
是否值得将smalltext(varchar 250)、imagpath(varchar 50)列排除在自己的表中,并将它们内部联接起来,这些列可能是我以后可能需要的过滤器。但是类型,性别,碎片都是小碎片。
有什么改进建议吗?
我应该在主查询之外的自己的查询中执行子查询吗?

编辑:31.07

SELECT a.* , c.cnt AS countanimals
        FROM animal  a
        JOIN (
            Select a1.date AS date1, a1.tmstmpadopt AS tmstmpadopt1, a1.type AS type1, COUNT(a1.id) as cnt 
            FROM animal a1
            GROUP BY date1, tmstmpadopt1, type1
            ) c on (a.date = c.date1 AND a.tmstmpadopt = c.tmstmpadopt1 AND a.type = c.type1)

        WHERE a.type = 1 AND tmstmpadopt = 0 AND (date BETWEEN  DATE_FORMAT(CURDATE() , '%Y-%m-%d') - INTERVAL 100 YEAR AND DATE_FORMAT(CURDATE(),'%Y-%m-%d')- INTERVAL 1 YEAR)
        ORDER BY a.timestamp DESC
        LIMIT 1, 20;
6jjcrrmo

6jjcrrmo1#

为什么不对脚本进行计数,在处理行时,可以对行进行计数。

sxpgvts3

sxpgvts32#

内联视图可以帮助您。所以试试这个

SELECT a.*,c.cnt AS countanimals
FROM animal a 
       join (Select a1.dateborn, a1.timestampadopt, count(a1.id) as cnt 
             from animals a1
             Where a1.timestampadopt > 0
               and a1.type = :type
             group by a1.dateborn, a1.timestampadopt) c on (a.dateborn = c.dateborn and a.timestampadopt = c.timestampadopt)
WHERE a.type = :type
AND a.timestampadopt > 0 
AND a.dateborn BETWEEN  DATE_FORMAT(CURDATE(),'%Y-%m-%d')-INTERVAL 1 YEAR AND DATE_FORMAT(CURDATE(),'%Y-%m-%d'))
ORDER BY a.timestamp DESC
LIMIT 1, 20;

相关问题