私は約5,000行のデータベースを持っています。多対多の関係も多数あります。私は、 "高度な検索"クエリの一環としてテーブル間でフリーテキスト検索を行う必要があります。強く型付けされたデータセットに対してLINQクエリが遅い
私は強く型付けされたデータセットを作成し、アプリケーションの起動時にSQL Serverからすべてのデータをインポートしました。データセットに対してLINQクエリを実行すると、クエリは非常にゆっくり実行されます(約15秒)。メモリ内のデータセットに対してクエリを実行するとSQL Serverよりもはるかに高速になると考えられましたが、そうは思われません。私はさらにwhere節に結合と "検索"を追加する必要があるので、事態が悪化するだけです。
私が検索しているフィールドでは、最長が「要約」で、データベースの中で最長のものが2,000バイト未満であるため、検索するデータがたくさんあるわけではありません。私は間違ったツリーをここで吠えているのですか、またはこのクエリのパフォーマンスを向上させる手段がありますか?
var results = from e in _data.ds.Employee
join es in _data.ds.EmployeeSkill on e.EmployeeId equals es.EmployeeId into esGroup from esItem in esGroup.DefaultIfEmpty()
join s in _data.ds.Skill on esItem?.SkillId equals s.SkillId into sGroup from skillItem in sGroup.DefaultIfEmpty()
join er in _data.ds.EmployeeRole on e.EmployeeId equals er.EmployeeId into erGroup from erItem in erGroup.DefaultIfEmpty()
join r in _data.ds.Role on erItem?.RoleId equals r.RoleId into rGroup from rItem in rGroup.DefaultIfEmpty()
join et in _data.ds.EmployeeTechnology on e.EmployeeId equals et.EmployeeId into etGroup from etItem in etGroup.DefaultIfEmpty()
join t in _data.ds.Technology on etItem?.TechnologyId equals t.TechnologyId into tGroup from tItem in etGroup.DefaultIfEmpty()
where
e.FirstName.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0 ||
e.LastName.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0 ||
e.RMMarket.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0 ||
!e.IsSummaryNull() && e.Summary.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0
select new SearchResult
{
EmployeeId = e.EmployeeId,
Name = e.FirstName + " " + e.LastName,
Title = e.Title,
ImageUrl = e.IsImageUrlNull() ? string.Empty : e.ImageUrl,
Market = e.RMMarket,
Group = e.Group,
Summary = e.IsSummaryNull() ? string.Empty : e.Summary.Substring(1, e.Summary.Length < summaryLength ? e.Summary.Length - 1 : summaryLength),
AdUserName = e.AdUserName
};
"インメモリ" LINQは、長年のRA/SQL最適化と統計収集/クエリプランの選択の恩恵を受けません。例えば。私はIndexOf上で「インデックスシーク」を実行する機会がないと考えています。これはSQL Server-LINQが(string.Containsを介して)行うことができます。 – user2864740
LINQはジョインをルックアップテーブルに変換するので、作業量が比較的多いにもかかわらず、まだ高速であるはずです。これが遅い場合、データセットを使用することとほぼ確実に関係します。 –
データを 'DataSet'sにロードしたり、クエリと動的に' join'するのではなく、POCO(クラスを作成するだけです)を使用してロード時に 'join'を事前実行することを検討してください。照会するたびにルックアップ・テーブルを作成します。これをCode Reviewに切り替えることを検討することもできます。 – NetMage