none
ある程度速いレスポンスが必要な.NETアプリではDBアクセスに何を使いますか? RRS feed

  • 全般的な情報交換

  • .NETアプリケーションを開発する場合、近年のデータアクセス層にはEntity Frameworkを利用するのが一般的だと認識しています。

    しかし、まだEntity Frameworkにはパフォーマンス懸念があるという話も耳に入り、
    そこそこ高レスポンスが求められるアプリケーションで提案していいものか、いまいち自信がありません。

    ケースバイケースなのはその通りなのですが、例えば新人プログラマに掲題のような質問をされた場合、なんと返しますか?
    皆様の意見を伺いたいです。

    なお、ここでは金融系で求められるような爆速システムではなく、
    ECサイトのようなエンタープライズ規模のデータ処理でも数秒くらいで返してほしい程度のアプリケーションを仮定しています。
    DBはSQL Serverの想定です。

    経験不足なりに色々ググってみたところ、個人的に整理した選択肢&特徴としては

    1.Entity Framework 6
      ・Code Firstが便利で生産性が高い

    2.接続型ADO.NET (SqlCommand,SqlDataReaderとか)
      ・低レイヤAPIで生産性が低いが、速い

    3.非接続型ADO.NET w/ 型なしDataSet (DataSet, DataAdapterとか)
      ・型なしなので色々不便だが、その分柔軟性がある

    4.非接続型ADO.NET w/ 型ありDataSet (型付きDataSet, TableAdapterとか)
      ・3のラッパーで使いやすいが、スキーマ拡張に弱い

    があって、

    速さでは 2 > 1 > 3 > 4
    生産性は 1 > 4 > 3 > 2
    スキーマ拡張耐性は 1 > 2 = 3 > 4

    という感覚です。

    なので答えとしては「実装コストがやや高いことを留意した上で接続型ADO.NET を選ぶ」と考えました。

    皆様はいかがでしょうか。

    2016年10月11日 8:55

すべての返信

  • ケースバイケースとしか言いようがありません。

    システムとしてどこまでのロールバックが認められるか、最近の搭載メモリ量から言ってもオンメモリも視野に入るため、RDBをそもそも持たず、Linq to Objectsで処理するという選択肢もあります。

    Entity Frameworkにパフォーマンスの懸念があるとのことですが、どの点に懸念があるのか、また求められるシステムではその懸念点を酷使するような設計となるのか、なども。(例えば更新が遅いという懸念があったとして、システムとしては更新頻度が低いなら関係なくなるわけです。また更新のみSqlCommandを使用するということもできるわけで。)

    1.~4.以外でDapperという声も聞きます。

    2016年10月11日 22:07
  • 私の場合は以下のようになります。あくまで参考として下さい。以下がベストというわけでもなんでもありません。
    私の場合は、95%ぐらいが4.で、5%ぐらいが2.で、3.は1%未満、1.は全く使っていません。

    Entity FrameworkはADO.NETを内包したフレームワークですが、同じようなものを私は作成して使っています。このフレームワークはどちらかというとアプリケーションレベルでデータベースに関する処理を包括するようなものです。例えば、監査のためのログ記録や、Entityに変更が加えられたかの検出、エラーチェック等です。今はWPFでMVVMを使用することが多いので、MVVMを強く意識しています。
    データベースを操作する場合、そのほとんどをストアドプロシージャで行います。速度も上がりますし、複雑なSQLやバッチ的なSQLも書きやすいからです。また、TableAdapterを多用します。

    2.はあまりお勧めしません。例えば、ピンポイントでちょっとデータを読みたいとか、ちょっとデータベースで処理を流したいというケースぐらいなら適していると思います。アプリケーションを一人で使う場合はまだ良いですが、複数人で使う場合は、同時実行制御を考えなければなりません。接続型の場合、つまり、悲観的ロックのデメリットが問題になることがあります。
    TableAdapterは楽観的ロック、かつ、同時実行制御に対応しています。おそらく私がTableAdapterを多用する一番の理由は同時実行制御の対応です。

    Entity Frameworkは、おそらくデータベースやSQLをあまり知らない人でもコードを書きやすくなるように設計されていると思います。同時実行制御にも対応しています。ADO.NETを生で使おうとすると、SQLを含めそれなりの知識が必要になります。
    しかし、本当に生産性が高く、速度が高いのはSQLに長け、ストアドプロシージャでに長けていることだと思います。ちょうどLINQを使うと生産性が上がるようなものです。LINQは決して速いとは言えませんが、ストアドプロシージャは速度でも有利です。誤解を恐れずに言えば、ストアドプロシージャはデータベース上で動作するLINQのようなものです。
    とはいうものの、決してEntity Frameworkを否定するものではなく、Entity FrameworkにはEntity Frameworkなりの良さがあり、用途があると思います。

    生産性を高める努力は、どのテクノロジーを使用しても忘れてはいけません。もちろん、速度を気にすることもです。テクノロジーを適材適所で使いつつ、それを利用して、生産性や速度を上げることを忘れないことが大切だと思います。テクノロジーに頼り、溺れないように注意されると良いと思います。


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    2016年10月12日 1:24
    モデレータ
  • > ECサイトのようなエンタープライズ規模のデータ処理でも数秒くらいで返してほしい程度のアプリケーションを仮定しています。

    Webサイトですか?
    Webなのかクライアント/サーバなのかとかでも違ってくるとこがあるような。

    で、

    > まだEntity Frameworkにはパフォーマンス懸念があるという話も耳に入り、

    バージョンがあがるにつれてパフォーマンスもあがってる、という話もありますが。

    まぁ、ある程度のデータ処理で数秒で返してほしい、というレベルだったらEntity Frameworkでもパフォーマンスが
    問題になることはなさそうな。
    どのようなSQL文が生成されるか考えながら作る必要はあるかもしれませんが。
    それよりDBの構成とかそっちのほうが問題になりそうな気はします。


    あおい情報システム株式会社 小野修司(どっとねっとふぁん)

    2016年10月13日 6:10
  • 私は基本 .NET エンジニアですが、昨年よりミドルウェア(データベース等)の勉強会に頻繁に参加してます。
    そこではパフォーマンスに関する話題がよく出ますが、話を聞くとパフォーマンスに問題あるシステムはプログラムよりサーバーの性能やクエリ・ネットワークに問題がある場合が多く、特にデータベース関連の問題では、テーブル設計やSQLに問題が多いように感じます。

    私自身が最近見聞きした事例では
    ・テーブルの正規化を行ったことで、プログラム側の検証処理が不要になり、アプリの性能が向上した。

    ・毎日数万件の更新が発生するテーブルがあるので、夜間バッチでインデックスを再構築するようにしたら、全般的に性能が向上した。

    ・Array を使い IN 句を動的に組み立てるクエリがあったので、一時テーブルを使うよう変更したら、トラフィック負荷が軽減しパフォーマンスの向上が見られた。

    ・Where 句の抽出条件の指定で、カーディナリティの高い順から行うようにしたら、インデックスを効果的に利用できるようになった。

    ・STRAIGHT_JOIN を使ってオプティマイザが駆動表と内部表を勝手に入れ替えないようにしたら、クエリが劇的に速くなった。

    などetc・・・

    一部、MySQL に特化した話もありますが、正規化やインデックスの問題、実行計画を意識したクエリの書き方については、あらゆるデータベースに共通の話になると思います。


    他の方も回答されてますが、DBアクセスに何使うかはあくまでケースバイケースで、速度面では極端な差はないでしょう。それよりも DB にアクセスする以上、リレーショナルモデルを意識した正しいDB設計と、データベース製品の特性を意識したクエリを書くことの方が、よりパフォーマンスに優れたシステムを開発できると考えます。


    以下、いくつか参考書籍を紹介しておきますが、なにかの参考になれば幸いです。内容については、各書籍のレビューを見て頂けばいいでしょう。個人的には SQL アンチパターンが最もお勧めです。

    SQLアンチパターン

    理論から学ぶデータベース実践入門

    SQL実践入門



    本フォーラムは、ユーザー(開発者)同士で情報交換を行うためのコミュニティです。初めて利用される方は、以下のアナウンスをご覧ください。 https://social.msdn.microsoft.com/Forums/ja-JP/ca9ecfb7-4407-4fcb-b8bd-207d68257e68?



    • 編集済み ひらぽんModerator 2016年10月14日 1:11 より理解を深めて頂くため、文中にリンクを追加した
    2016年10月13日 13:12
    モデレータ
  • 確かに、一つのシステム内で色々組み合わせる、というのも手ですね。
    Dapperは把握できていませんでした。ご紹介ありがとうございます。
    2016年10月14日 16:00
  • なるほど、同時実行制御についての対応可否については、意識できていませんでした。
    興味があるので、それぞれ特徴を整理しなおしてみたいです。

    生産性を高める継続的な努力が必要、ということも同感です。
    2016年10月14日 16:00
  • Entity Frameworkは更改も早くて、現状のパフォーマンスがどれくらいなのか、正直把握しづらいですよね。
    おっしゃる通り、今ではもう対してパフォーマンス懸念も少ないかもしれないので、まずは実際に計ってみるというのも手かもしれません。
    2016年10月14日 16:01
  • 書籍の紹介、ありがとうございます。
    ぜひ参考にさせていただきます。

    DALに極端な差がない、というのも一理あるなと思いました。
    となると、特にどんなSQLが発行されるのか直感的にわかりにくいEntity Frameworkは、やはり若干懸念がありますね。
    オーバーヘッドなどより、そこが一番の致命傷になりそうな気も。
    2016年10月14日 16:01
  • 質問文には「経験不足なりに色々ググってみたところ、個人的に整理した選択肢&特徴としては」とありましたがDapperには辿り着けていなかったということですね。疑問なのはどのような調べ方をしたのでしょうか? 普通の調べ方では教科書的な説明ばかりヒットするはずで、本スレッドの趣旨である「ECサイトのようなエンタープライズ規模のデータ処理でも数秒くらいで返してほしい程度のアプリケーション」からかけ離れた記述に惑わされていたりしませんか?

    「using CSharp;」な企業を支える技術方針とベスト.NETライブラリのような記事にたどり着くはずで、Dapperを見逃す時点で調べ方に問題があると思います。

    ちなみに何らかの記事で「Entity Frameworkにはパフォーマンスに問題がある」と書かれていたらそのまま問題があると受け取るのでしょうか? 話にはコンテキストというものがあります。既に指摘されているように記事が古く評価したバージョンが過去のものの可能性もありますし、筆者の理解力不足で勘違いしたまま記事になっていることもあります。そうでなくとも何と比較したのかを合わせて理解しないと言葉だけ独り歩きしていつの間にか「Entity Frameworkは絶対的に遅い」と読み違えてしまっては意味がありません。

    2016年10月14日 21:54
  • > どのような調べ方をしたのでしょうか?
    まず背景として。
    上記1~4は、全てこれまで自分自身で利用したことのあるものです。
    今はEntity Framework Coreを使った開発に携わっています。

    が、いづれのケースも小規模のアプリケーションで、数万・数十万を超える規模のデータを扱ったことはありませんでした。
    近々、複数の少しデータ規模の大きなシステム開発に参画する可能性が出てきたため、事前調査をしたいと思いました。

    なので、これら過去に使ったことのある技術のパフォーマンス面を調べて、想定ケースではどれが適しているのか、確認しようとしました。
    そこでDapperに辿り着けなかったのは、おっしゃる通り、調べ方に問題があったと思っています。
    シーズベースではなくニーズベースで検索すべきでした。
    精進します。

    > ちなみに何らかの記事で「Entity Frameworkにはパフォーマンスに問題がある」と書かれていたらそのまま問題があると受け取るのでしょうか?
    そんなつもりは一切ありません。
    情報を一面的に取捨選択したくなかったため、広く様々な方の意見を聞いてみたく、「質問」ではなく「ディスカッション」として投稿させていただきました。

    2016年10月16日 5:52
  • そんなつもりは一切ありません。情報を一面的に取捨選択したくなかったため、広く様々な方の意見を聞いてみたく、「質問」ではなく「ディスカッション」として投稿させていただきました。

    そのような背景でしたか。了解しましたが、(まだ未完成と言っても過言ではない)Entity Framework Coreを既に使用されているにもかかわらず「まだEntity Frameworkにはパフォーマンス懸念があるという話も耳に入り」というのも若干不可解です。
    「パフォーマンス懸念があるという話」に対してそのまま問題があると受け取るわけではない、つまり既にご自身で真偽を確認されていて、その上でEF Coreを使用されている、そうおっしゃられているのであればEFに於いてデータ規模に依存する問題の有無は把握されているのではないでしょうか?

    ちなみに速さだけでなく早さについて非同期機能はどうお考えでしょうか? SqlDataReader.ReadAsync()やそれに対応したQueryableExtensions.ToListAsync()などはありますが、DataSetにはなかったと思います。

    ちょうどexe起動時に時間が掛かる理由がentityframeworkが原因なのか?を教えてください。スレッドも参考になるかと思います。

    2016年10月16日 22:40
  • 書籍の紹介、ありがとうございます。
    ぜひ参考にさせていただきます。

    DALに極端な差がない、というのも一理あるなと思いました。
    となると、特にどんなSQLが発行されるのか直感的にわかりにくいEntity Frameworkは、やはり若干懸念がありますね。
    オーバーヘッドなどより、そこが一番の致命傷になりそうな気も。
    データベース製品によります。

    MySQL・・・特に5.6までは、オプティマイザが他製品に比べ弱かったため、デザイン時にクエリを自動生成するツールとは決定的に相性が悪かったと思ってます。最新版の5.7でオプティマイザが劇的に改善されたので、TableAdapter 等で自動生成されるクエリでも十分パフォーマンスが期待できるのではないかと思ってます。ただしログに保存されるクエリは相変わらず読みにくいことが想像できます(苦笑)

    また Entity Framework は、なんといってもコードファーストが魅力ですし SQL Server との相性も抜群だと思われます。本当に速さを求めるなら、サーバー(クラウド)の設定やデータ構造やクエリ等、Entity Framework とは別な話になると思います。

    本フォーラムは、ユーザー(開発者)同士で情報交換を行うためのコミュニティです。初めて利用される方は、以下のアナウンスをご覧ください。 https://social.msdn.microsoft.com/Forums/ja-JP/ca9ecfb7-4407-4fcb-b8bd-207d68257e68?

    2016年10月17日 4:26
    モデレータ
  • > EFに於いてデータ規模に依存する問題の有無は把握されているのではないでしょうか?

    これまで私が携わっているのはデータ数が限定的(トランザクションデータでも一度の処理が数千程度)なシステムのみで、
    そのケースで言えばEFでもパフォーマンス問題は起こっていません。
    生産性も高いことから、積極的にEFを採用しています。

    一方で、データ件数が2桁・3桁も違うケースの場合については経験がありません。
    そういうケースではADO.NETを採用する手もあるのかなと考えていたところ、他の方々はどう考えているのか興味が出たため、この投稿をした次第です。

    > ちなみに速さだけでなく早さについて非同期機能はどうお考えでしょうか?

    DataSetのデメリットの一つだと思います。Asyncメソッドが標準提供されていない場合、その分自作しなければいけないリスク・コストは考えなければなりませんよね。
    ご指摘、および参考スレッドの紹介、ありがとうございます。

    2016年10月18日 12:56
  • MySQL周りは最近あまり追えていませんでしたので、知りませんでした。
    なるほど。
    それにログの可読性も考えなければならない指標ですね。
    あまり気にしていない視点でした。ありがとうございます。

    SQL ServerとEntity Frameworkの組み合わせは本当に便利だと思います。
    でもだからこそ、任せきりにせずデータ構造やDB側の設定をちゃんと考えないといけないですね。

    2016年10月18日 13:04