2

linqとgroupby式を使用するメソッドがあります:

public List<SerieVu> ListSeriesLesPlusVuesSemaine()
{
    DateTime dateIlYaSeptJours = DateTime.Now.AddDays(-7);

    var resultat =
    from uev in Query(uev => uev.userepivu_date > dateIlYaSeptJours)
    group uev by uev.Episode.Saison.Serie into pgroup
    let count = pgroup.Count()
    orderby count descending
    select new SerieVu() { nombreDeVus = count, Serie = pgroup.Key };

    return resultat.Take(7).ToList();
}

このlinqクエリは、このSQLクエリを生成します。

SELECT TOP (7) [Project1].[C2]                        AS [C1],
               [Project1].[C1]                        AS [C2],
               [Project1].[serie_id]                  AS [serie_id],
               [Project1].[serie_image]               AS [serie_image],
               [Project1].[serie_image_thumb]         AS [serie_image_thumb],
               [Project1].[serie_format]              AS [serie_format],
               [Project1].[serie_motsclefs]           AS [serie_motsclefs],
               [Project1].[serie_statusproduction_id] AS [serie_statusproduction_id],
               [Project1].[serie_nom]                 AS [serie_nom],
               [Project1].[serie_nomvf]               AS [serie_nomvf],
               [Project1].[serie_synopsis]            AS [serie_synopsis],
               [Project1].[serie_syncthetvdb]         AS [serie_syncthetvdb],
               [Project1].[serie_dateajout]           AS [serie_dateajout],
               [Project1].[serie_datemiseajour]       AS [serie_datemiseajour],
               [Project1].[serie_actif]               AS [serie_actif],
               [Project1].[utilisateur_id]            AS [utilisateur_id],
               [Project1].[serie_francais]            AS [serie_francais]
FROM   (SELECT [GroupBy1].[A1]  AS [C1],
               [GroupBy1].[K1]  AS [serie_id],
               [GroupBy1].[K2]  AS [serie_image],
               [GroupBy1].[K3]  AS [serie_image_thumb],
               [GroupBy1].[K4]  AS [serie_format],
               [GroupBy1].[K5]  AS [serie_motsclefs],
               [GroupBy1].[K6]  AS [serie_statusproduction_id],
               [GroupBy1].[K7]  AS [serie_nom],
               [GroupBy1].[K8]  AS [serie_nomvf],
               [GroupBy1].[K9]  AS [serie_synopsis],
               [GroupBy1].[K10] AS [serie_syncthetvdb],
               [GroupBy1].[K11] AS [serie_dateajout],
               [GroupBy1].[K12] AS [serie_datemiseajour],
               [GroupBy1].[K13] AS [serie_actif],
               [GroupBy1].[K14] AS [utilisateur_id],
               [GroupBy1].[K15] AS [serie_francais],
               1                AS [C2]
        FROM   (SELECT [Extent4].[serie_id]                  AS [K1],
                       [Extent4].[serie_image]               AS [K2],
                       [Extent4].[serie_image_thumb]         AS [K3],
                       [Extent4].[serie_format]              AS [K4],
                       [Extent4].[serie_motsclefs]           AS [K5],
                       [Extent4].[serie_statusproduction_id] AS [K6],
                       [Extent4].[serie_nom]                 AS [K7],
                       [Extent4].[serie_nomvf]               AS [K8],
                       [Extent4].[serie_synopsis]            AS [K9],
                       [Extent4].[serie_syncthetvdb]         AS [K10],
                       [Extent4].[serie_dateajout]           AS [K11],
                       [Extent4].[serie_datemiseajour]       AS [K12],
                       [Extent4].[serie_actif]               AS [K13],
                       [Extent4].[utilisateur_id]            AS [K14],
                       [Extent4].[serie_francais]            AS [K15],
                       COUNT(1)                              AS [A1]
                FROM   [dbo].[UtilisateurEpisodeVu] AS [Extent1]
                       INNER JOIN [dbo].[Episode] AS [Extent2]
                         ON [Extent1].[episode_id] = [Extent2].[episode_id]
                       INNER JOIN [dbo].[Saison] AS [Extent3]
                         ON [Extent2].[saison_id] = [Extent3].[saison_id]
                       LEFT OUTER JOIN [dbo].[Serie] AS [Extent4]
                         ON [Extent3].[serie_id] = [Extent4].[serie_id]
                WHERE  [Extent1].[userepivu_date] > '2013-01-11T09:53:26' /* @p__linq__0 */
                GROUP  BY [Extent4].[serie_id],
                          [Extent4].[serie_image],
                          [Extent4].[serie_image_thumb],
                          [Extent4].[serie_format],
                          [Extent4].[serie_motsclefs],
                          [Extent4].[serie_statusproduction_id],
                          [Extent4].[serie_nom],
                          [Extent4].[serie_nomvf],
                          [Extent4].[serie_synopsis],
                          [Extent4].[serie_syncthetvdb],
                          [Extent4].[serie_dateajout],
                          [Extent4].[serie_datemiseajour],
                          [Extent4].[serie_actif],
                          [Extent4].[utilisateur_id],
                          [Extent4].[serie_francais]) AS [GroupBy1]) AS [Project1]
ORDER  BY [Project1].[C1] DESC

私の質問は、このクエリのパフォーマンスを改善する方法ですか?私のウェブサイトの非常に重要なページで約6秒かかります。

ご協力ありがとうございました

4

3 に答える 3

1

データベースにいくつかのインデックスを作成することから始めることができます。フィールド フォーム where、order by、group by をインデックスに配置する必要があります。この WHERE [Extent1].[userepivu_date ] > '2013-01-11T09:53:26' はテーブル全体をスキャンします

SQL Server でのインデックスの作成:

CREATE INDEX [indexname] ON Extent1 (userepivu_date)
于 2013-01-18T09:45:04.453 に答える
1

私は解決策を見つけました。明示的な結合を使用して内部結合を強制しました:

public List<SerieVu> ListSeriesLesPlusVuesSemaine()
{
    DateTime dateIlYaSeptJours = DateTime.Now.AddDays(-7);

    ObjectSet<UtilisateurEpisodeVu> UtilisateurEpisodeVuSet = _context.CreateObjectSet<UtilisateurEpisodeVu>();
    ObjectSet<Episode> EpisodeSet = _context.CreateObjectSet<Episode>();
    ObjectSet<Saison> SaisonSet = _context.CreateObjectSet<Saison>();
    ObjectSet<Serie> SerieSet = _context.CreateObjectSet<Serie>();

    var resultat =
    from uev in UtilisateurEpisodeVuSet.Include("Episode.Saison.Serie").Where(uev => uev.userepivu_date > dateIlYaSeptJours)
    join e in EpisodeSet on uev.episode_id equals e.episode_id
    join sai in SaisonSet on e.saison_id equals sai.saison_id
    join s in SerieSet on sai.serie_id equals s.serie_id
    group uev by s into pgroup
    let count = pgroup.Count()
    orderby count descending
    select new SerieVu() { nombreDeVus = count, Serie = pgroup.Key };

    return resultat.Take(7).ToList();
}

このメソッドを使用すると、linq クエリは内部結合のみを生成します ;) 助けてくれた皆さんに感謝します

于 2013-01-18T17:47:51.870 に答える
1

最初にアドバイスすることは、実行計画を見てボトルネックを探すことです

それでは、なぜそこに LEFT OUTER JOIN があるのでしょうか?

LEFT OUTER JOIN [dbo].[Serie] AS [Extent4]

内部結合ではありませんか (そうであれば、マッピングに問題がある可能性があります)。結合プロセスの早い段階で where 句が実行されないようにすることで、クエリの最適化を台無しにする可能性があると思います。

おそらく、左外部結合を内部結合に置き換えてクエリを実行し、違いが生じるかどうかを確認できます。また、@ user1802430 に同意します。userepivu_date にインデックスがない場合は、必ず配置する必要があります。

于 2013-01-18T10:17:59.643 に答える