IT SQL

【SQL Server】「あー、遅い!」Webシステムが遅くなる原因3つ

悩んでる人
開発者「最近開発した機能をリリースした後、全体的にシステムが遅くなった気がするけど、何が原因なのかな?」

こんな悩みに答えます。

この記事を読むことで、Webシステムが遅くなる原因を理解し、システムが遅くなる原因となる実装を行わない方法を学ぶことができます。

今回はタイトルに記載した通りSQLに関しての話がメインで、実務でよくあるパターンを3つ選びました。

それでは、早速解説していきたいと思います。

SELECT * を使用したクエリを発行し、不要なカラムまで取得している

Webシステムが遅くなる1つ目の理由は、SQL発行時に 「SELECT * FROM ~」 で不要なカラムまで取得しているパターンです。

例えば、100個のカラムが存在しているテーブルがあり、そこから5カラム分の情報を10,000行取得したかったとしましょう。

「SELECT *」を使用してクエリを発行した場合はすべての列情報を取得するので、 100 * 10,000 で 1,000,000 フィールドの情報を取得します。

しかし、5カラム分に絞り込んで列情報を取得した場合は、 5 * 10,000 で 50,000 フィールドの情報のみ取得しますので、取得するフィールド数は * 指定に比べて 1/20 に低減することができます。

このように * 指定で不要なカラムまで取得することによってパフォーマンスが低下することがありますので、明示的にカラムを指定できる場合は必要なカラムのみを指定してクエリを発行するようにしましょう。

ループ処理の中で SQL を発行している

Webシステムが遅くなる2つ目の理由は、ループ処理の中で SQL を発行している箇所があるパターンです。

これはアプリケーション側の処理に関しての話ですが、以下のような処理があったとします。

foreach(var order in orders) {
// DB から hoge プロパティの値を取得する
order.hoge = GetHogeById(order.id);
}

上記の場合、orders の数分 hoge プロパティの値を取得するために DB へクエリ発行を行っています。

極端な例でいうと、orders の件数が1万件があった場合は、1万回クエリが発行されますので、orders の件数が増えるごとにパフォーマンスが低下していくことが目に見えています。

そのため、orders 自体を取得する際に hoge プロパティの値も取得するなどの工夫を行い、少しでもクエリの発行を減らすようにしましょう。

SQL Server の統計情報が古い

Webシステムが遅くなる最後の理由は、SQL Server の統計情報が古いパターンです。

統計情報とは、ざっくり説明すると表(テーブル)や索引(インデックス)、列(カラム)の値やレコード件数などの情報が記録されたもののことです。

SQL Server では統計情報を元に、テーブルに対してどのように検索を行い、どのようにデータを取得するかが書かれた実行計画と呼ばれるものを作成します。

そして作成された実行計画を元にデータアクセスを行うという流れになるので、古い統計情報のままだと最適な実行計画を作成することができず、効率の悪いデータアクセスを行ってしまう可能性があります。

そのため、SQL のパフォーマンスが落ちているなと感じたら、統計情報を更新することでパフォーマンスの低下が解消される場合もあります。

まとめ

  • 「SELECT *」を使用してクエリを発行していることで、不要なカラムを取得し、パフォーマンスが低下している可能性がある
  • ループ処理の中で SQL を発行していること、でクエリ発行回数が多くなり、パフォーマンスが低下している可能性がある
  • 統計情報が古いことで、最適な実行計画が立てられず、パフォーマンスが低下している可能性がある

いかがでしたでしょうか?

この記事で紹介したもの以外にもパフォーマンスを低下させてしまう要因はたくさんあるのですが、この記事を読んで実はパフォーマンスが低下してしまう実装を行ってしまっていた … という方がもしかしたらいるかも知れません。

パフォーマンスの低下は UX の低下にも繋がり、EC などを運営している事業者にとっては売上の低下にもつながってしまいます。

そのため、普段からパフォーマンスが低下する実装を避け、ビジネスに影響を出さないように注意しながら実装を行うように心がけましょう!

-IT, SQL

Copyright© ナガブログ , 2020 All Rights Reserved.