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

时间:2018-07-30 08:58:45

标签: mysql query-optimization sql-optimization

我正在尝试改善我的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种动物必须使用next按钮。

对于分页,我需要知道必须显示多少个站点,所以我必须计算总共有多少只动物,这就是子查询的作用。

我通过分析时间进行测量,并得到以下结果:

0.0047s 用于总查询,
0.0023s (用于子查询)

数据库中只有 5行

在该站点上,我提供了一些过滤器,例如+/- 1岁,并且已经被采用,因此,我都需要WHERE子句,这可能会占用最多的性能,其次是order by子句首先需要显示新的内容。

P.S。我需要表中的所有列,我做了一些测试,SELECT *具有相同的运行时,然后像某些人建议的那样手动选择了所有10列。

编辑:
值得在自己的表中排除smalltext(varchar 250),imagpath(varchar 50)列并内部联接它们,其他列可能是我以后需要过滤的地方。但是类型,性别,残缺是tinyints。

对我来说有什么改善秘诀吗?

我应该在主查询之外的自己的查询中执行子查询吗?

编辑: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;

2 个答案:

答案 0 :(得分:1)

内联视图可能会对您有所帮助。所以试试这个

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;

答案 1 :(得分:0)

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