Php ecord保存在comments中,它会触发“comments\u counter”表中的更新,或者类似的东西?这将为您提供一些性能,因为您不需要按操作分组的最大计数

Php ecord保存在comments中,它会触发“comments\u counter”表中的更新,或者类似的东西?这将为您提供一些性能,因为您不需要按操作分组的最大计数,php,mysql,sql,performance,Php,Mysql,Sql,Performance,此外,match\u of_comments.match\u id=f2.match\u static\u id有不同的数据类型,第一个是varchar(255),第二个是int(25)-将两者都设为int(25)应有助于提高整体性能 最后,我将注释中的user\u id也作为user.id的外键。我使用了一个分析函数。但由于没有数据供我测试,我不太确定这是否是最佳的 SELECT * FROM ( SELECT DISTINCT f1.match_static_id,

此外,match\u of_comments.match\u id=f2.match\u static\u id有不同的数据类型,第一个是varchar(255),第二个是int(25)-将两者都设为int(25)应有助于提高整体性能


最后,我将注释中的user\u id也作为user.id的外键。

我使用了一个分析函数。但由于没有数据供我测试,我不太确定这是否是最佳的

SELECT * 
FROM
(
    SELECT DISTINCT f1.match_static_id,
                    users.username,
                    users.id,
                    matches_of_comments.localteam_name,
                    matches_of_comments.visitorteam_name,
                    matches_of_comments.localteam_goals,       
                    matches_of_comments.visitorteam_goals,
                    matches_of_comments.match_status,
                    new_iddaa.iddaa_code,
                    @MAX_TIMESTAMP AS `FIRST_VALUE(MATCH_STATIC_ID) OVER(partition by f1.match_static_id ORDER BY F1.TIMESTAMP DESC)`,
                    @COMMENTS_NO AS `COUNT(1) OVER(partition by f1.match_static_id)`,
                    F1.TIMESTAMP
    FROM comments AS f1
    INNER JOIN users ON users.id = f1.user_id
    INNER JOIN matches_of_comments 
    ON matches_of_comments.match_id = f1.match_static_id
    AND matches_of_comments.flag =1
    LEFT JOIN new_iddaa 
    ON new_iddaa.match_id = matches_of_comments.match_id
) A
WHERE @MAX_TIMESTAMP = TIMESTAMP
ORDER BY @MAX_TIMESTAMP DESC

在讨论选择之前,先从更紧迫的问题开始


第一个紧迫的问题是:

SELECT DISTINCT …
select distinct
速度较慢。非常非常慢:它基本上比较集合返回的每行的每个字段。当其中有一个
ID
保证每行都是唯一的时,自然会有优化的空间,但您自己的查询看起来并没有提供任何这样的可能性:充其量是
中的一个元组匹配\u个注释
新的\u iddaa

要解决这个问题,请将查询分为两个或多个部分,并仅获取您正在执行的操作实际需要的内容。这似乎是按评论的最新评论日期排序
匹配的评论,然后从
用户
新iddaa
获取额外的美容数据

下一个问题是imho最大的问题:

INNER JOIN (
         SELECT match_static_id,
                MAX( TIMESTAMP ) maxtimestamp,
                COUNT( match_static_id ) AS comments_no
         FROM comments
         GROUP BY match_static_id
      ) AS f2 ON f1.match_static_id = f2.match_static_id 
              AND f1.timestamp = f2.maxtimestamp
您将聚合与
(match\u static\u id,timestamp)
元组上的一个表连接起来,该元组上没有索引,并获取一个庞大的集合。你有一个保证合并连接的道路-不是你想要的

最后一个引人注目的问题是:

ORDER BY f2.maxtimestamp DESC
首先,你没有限制。这意味着您将构建、排序并返回一个庞大的集合。当然,您正在为这些数据分页,所以在查询中添加一个limit子句

一旦添加了限制,就需要考虑添加额外行的内容,以及如何排序它们。根据你的模式,我想新的iddaa是这样的。您是否以这样一种方式对内容进行分页,即后一种信息需要成为该查询的一部分以及它返回的行数?我想不会,因为您显然对这些行的排序方式不感兴趣

扫描模式后,会弹出另一个模式:

`match_id` varchar(255)
引用这个的行是整数,对吗?因此,它也应该是一个整数,以避免将varchar强制转换为int或将varchar强制转换为int的开销,并允许在任何情况下使用索引

虽然与此特定查询无关,但以下两个字段也需要注意并进行适当的转换:

`tournament_id` varchar(255)
`match_time` varchar(255)
`match_date` varchar(255)
`static_id` varchar(255)
`fix_id` varchar(255)
`localteam_id` varchar(255)
`visitorteam_id` varchar(255)

关于改进查询

正如我所读到的,您正在按最新注释排序
匹配注释中的注释。您还需要评论的数量,所以我们从这开始。假设您正在对许多查询中的前10个进行分页,查询如下所示:

SELECT match_static_id,
       MAX( TIMESTAMP ) maxtimestamp,
       COUNT( match_static_id ) AS comments_no
FROM comments
GROUP BY match_static_id
ORDER BY maxtimestamp DESC
LIMIT 10 OFFSET 0
就这些

它会给你10个ID-如果你增加限制的话会更多。在你的应用程序中循环使用它们,并在(…)
子句中构建一个
,该子句允许你根据需要从其他表中获取每一位数据;您可以通过一个或多个查询来实现这一点,这无关紧要。关键是要避免加入该聚合,以便后续查询可以使用索引


通过完全删除上述查询,您还可以更显著地改进

为此,将三个字段添加到
匹配的\u注释
,即
last\u comment\u timestamp
last\u comment\u user\u id
,以及
num\u comments
。使用触发器维护它们,并在
(标志,最后一次注释时间戳)
上添加索引。这将允许您运行以下高效查询:

SELECT matches_of_comments.static_id,
       matches_of_comments.num_comments,
       matches_of_comments.last_comment_timestamp,
       matches_of_comments.last_comment_user_id,
       matches_of_comments.localteam_name,
       matches_of_comments.visitorteam_name,
       matches_of_comments.localteam_goals,       
       matches_of_comments.visitorteam_goals,
       matches_of_comments.match_status
FROM matches_of_comments
WHERE matches_of_comments.flag = 1
ORDER BY matches_of_comments.last_comment_timestamp DESC
LIMIT 10 OFFSET 0

然后,您只需要从
用户
新iddaa
中选择所需的数据-使用前面讨论过的
in(…)
子句中的单独查询。

您能将一些示例数据添加到此SQLFIDLE中吗?然后,它将有助于其他人进行检查。首先,您需要在
(match\u static\u id,timestamp)
上建立索引,以使派生表有效。
中的列类型匹配
match\u id
的\u注释
与该列不匹配的其他两个表。当您尝试加入该索引时,这会使您付出巨大代价。正如您所看到的,我将这两列作为索引,并在on语句中使用match_static_id,但在EXPLAIN中没有显示这一点。我想知道如何在派生语言中使用它们table@WillemRenzema所以我应该把它们全部改成一种类型??但这又如何反映在结果上呢。
SELECT match_static_id,
       MAX( TIMESTAMP ) maxtimestamp,
       COUNT( match_static_id ) AS comments_no
FROM comments
GROUP BY match_static_id
ORDER BY maxtimestamp DESC
LIMIT 10 OFFSET 0
SELECT matches_of_comments.static_id,
       matches_of_comments.num_comments,
       matches_of_comments.last_comment_timestamp,
       matches_of_comments.last_comment_user_id,
       matches_of_comments.localteam_name,
       matches_of_comments.visitorteam_name,
       matches_of_comments.localteam_goals,       
       matches_of_comments.visitorteam_goals,
       matches_of_comments.match_status
FROM matches_of_comments
WHERE matches_of_comments.flag = 1
ORDER BY matches_of_comments.last_comment_timestamp DESC
LIMIT 10 OFFSET 0