有啥办法可以优化这个 SQL 语句?

Posted

技术标签:

【中文标题】有啥办法可以优化这个 SQL 语句?【英文标题】:Any way I could optimize this SQL statement?有什么办法可以优化这个 SQL 语句? 【发布时间】:2014-03-04 04:40:10 【问题描述】:

所以我的查询确实有效,但大约需要 25-30 秒才能完成。我想知道我是否可以对这个查询做些什么来优化它,让它运行得更快一点?我自己做了一些,但它仍然最多运行 25 秒左右。

有什么建议或帮助吗?即使只是在正确方向上的一点也将不胜感激。

    SELECT * FROM `earnfrom` WHERE (
            `active` = ? AND `type` = ?
    )
    AND `curdaily` <= `dailyclick` AND `clicks` <= `totalclick` AND `id` NOT IN (
        SELECT `earnid` FROM `earnedby` WHERE `userid`= ?
    )
    AND `userid` != ? AND  (
        SELECT `points` FROM `users` WHERE `id` = `userid`
    ) >= `cpc` ORDER BY `cpc` DESC, RAND()")

这是表格方案:

TABLE 获得者: earnedby

TABLE 收入来源: earnfrom

TABLE 用户: prntscr.com/2xpmre

DB 有 2711 个相同类型的链接(Facebook Likes),它需要获取那些没有被点赞的链接(NOT IN (SELECT * FROM `....),但 NOT IN 很痛苦,因为一周(因为我每天有超过 210 个用户)

所以查询应该这样做:

从数据库中选择一个链接,验证每日限制点击是否相等,选择不相等的人,验证id是否存在于另一个表(earnedby)中作为earnid,如果不是应该是好的,如果存在就是真的已经喜欢了,或者喜欢的时候有问题

谢谢你考虑我的问题~

【问题讨论】:

没有查询计划 -> 没有帮助。 添加了更好的描述~ 谁在乎描述,查询计划是什么 “查询计划”是什么意思? 更新了,你是这个意思吗? 【参考方案1】:

通过适当的连接将子查询从 WHERE 部分移动到 FROM 部分。

例如像这样

SELECT * FROM `earnfrom` 
    join `users` on `users`.`id` = `earnfrom`.`userid` 
    left join (select `earnid` from FROM `earnedby` WHERE `userid`= ?) sub ON sub.`earnid`=`earnfrom`.`userid`
WHERE (
        `active` = ? AND `type` = ?
)
AND `curdaily` <= `dailyclick` 
AND `clicks` <= `totalclick` 
AND sub.`earnid` is NULL
AND `userid` != ? AND  `users`.`points` >= `cpc` 
ORDER BY `cpc` DESC, RAND()")

【讨论】:

谢谢你做得很好,我希望我能给你一个拥抱先生:) 不客气。 :-) 不要忘记接受正确的答案。 完成,谢谢,使用你的 + 将 != 更改为 我的查询现在运行不到 1 秒。 :)【参考方案2】:

我不是 mysql 专家,所以我使用 Percona Query Adviser 在实施之前分析我的查询。这是一个很好的起点。

https://tools.percona.com/query-advisor/

【讨论】:

谢谢,这确实帮了大忙!

以上是关于有啥办法可以优化这个 SQL 语句?的主要内容,如果未能解决你的问题,请参考以下文章

有啥办法直接对c#中的datatable使用sql语句进行筛选呢

plsql 为啥隔几分钟再执行sql的时候就会未响应,有啥办法可以解决不?

存储过程和sql语句有啥区别

这个 My-SQL 语句有啥问题?

sql语句中嵌套时候用in 和=有啥区别

SQL优化案例一