【问题标题】:Database index for 'most recent' window function query“最近”窗口函数查询的数据库索引
【发布时间】:2020-09-08 23:12:37
【问题描述】:

我有一个user 表和一个media 表。媒体表有一个指向用户表 (UserID) 的外键,以及一个 metaDate(捕获日期)列。

我想创建一个视图来显示与每个用户关联的最近更新的媒体。我目前正在尝试使用窗口函数来创建视图:

CREATE VIEW `user_last_media` AS
select `m`.`UserID` AS `UserID`,`m`
.`MediaID` AS `MediaID`
,`m`.`CaptureDate` AS `CaptureDate`
,`m`.`ThumbnailFile` AS `ThumbnailFile` 
from (
    with ranked_media as
    (
        select `m`.`UserID` AS `UserID`
        ,`m`.`ID` AS `MediaID`
        ,`m`.`metaDate` AS `CaptureDate`
        ,`m`.`thumbnailFile` AS `ThumbnailFile`
        ,row_number() over (partition by `m`.`UserID` order by `m`.`metaDate` desc) AS `rn` 
        from `media` `m` 
        where `m`.`shared` = 1 
        and `m`.`UserID` is not null
    )
    select `ranked_media`.`UserID` AS `UserID`
    ,`ranked_media`.`MediaID` AS `MediaID`
    ,`ranked_media`.`CaptureDate` AS `CaptureDate`
    ,`ranked_media`.`ThumbnailFile` AS `ThumbnailFile` 
    from `ranked_media` where `ranked_media`.`rn` = 1
) `m`

我尝试在media表上应用索引,使用UserIDsharedmetaDatathumbnailFileID,但是这个视图本身的性能不是很好好(通过UserID 获得一条记录的查询大约需要1 秒)。请注意,media 表中有大约 200,000 条记录和大约 5,000 个不同的 UserID 值。

一旦我尝试将此视图与用户表连接以获取每个用户的更多信息,性能会变得更差(3-4 秒)。我该如何改进我的方法?我想应用适当的索引以在 0.5 秒内获得此查询。

【问题讨论】:

    标签: sql indexing mariadb


    【解决方案1】:

    公用表表达式增加了不必要的复杂性。您可以将其简化为:

    create view `user_last_media` as
    select `UserID` AS `UserID`, `ID` AS `MediaID`, `metaDate` AS `CaptureDate`, `thumbnailFile` AS `ThumbnailFile`
    from (
        select m.*, 
            row_number() over (partition by `m`.`UserID` order by `m`.`metaDate` desc) AS rn
        from `media` `m` 
        where `m`.`shared` = 1 and `m`.`UserID` is not null
    ) m
    where rn = 1
    

    可能利用(shared, userID, metadate)上的索引。

    您也可以尝试使用相关子查询而不是窗口函数:

    select `UserID` AS `UserID`, `ID` AS `MediaID`, `metaDate` AS `CaptureDate`, `thumbnailFile` AS `ThumbnailFile`
    from `media` m
    where 
        `shared` = 1 
        and `UserID` is not null
        and medaDate = (
            select max(m1.date)
            from `media` m1
            where `shared` = 1 and m1.`UserID` = m.`userID`
        )
    

    不相关的注释:每个标识符周围的反应只是噪音。让您的生活更轻松!在创建表时使用不带引号的标识符,因此您以后无需在查询中引用它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 2018-06-05
      • 2015-06-14
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 2021-07-09
      相关资源
      最近更新 更多