1

今日はコメントを読んで実験をしました。いくつかの座標を保存するシステムを想像しました。

状況は次のとおりです。

私は2つのテーブルを持っています、最初は:

CREATE TABLE Points
(
ID int IDENTITY(1,1) PRIMARY KEY,
X int,
Y int,
Name varchar(20),
Created datetime
)

座標(100万行)を保存しているだけです。2つ目は、選択によく使用されるポイント(約1100行)を格納するヘルパーテーブルです。

CREATE TABLE PointSearchHelper
(
X int,
Y int
)

これまでのところ元気です。

簡単に選択したいのですが:

SELECT p.* FROM Points p 
INNER JOIN PointSearchHelper h
ON p.X = h.X AND p.Y = h.Y

スクリプトを実行すると、平均で約280ミリ秒で1100行が取得されます。

実行プランを確認すると、SQL Server 2008 R2がインデックスを推奨していることがわかります(誰が考えたでしょうか?;)):

CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[Points] ([X], [Y])
INCLUDE ([ID], [Name], [Created])

これはテーブルの完全なインデックスであり、各列が含まれています。比較するとサイズが「巨大」で、データを2回保存しています。

したがって、クエリnoははるかに高速です。約75ミリ秒(!)非常に大きな改善ですが、この改善はほぼ2倍のスペースが必要です。

私の質問は単純です。列のSQLServerに、値を格納する方法や、二重ストレージから身​​を守るためのその他のトリックを指示する方法はありますか?

アップデート:

言い換えれば、同じパフォーマンスで「フルインデックス」を回避するためのトリックはありますか?

4

5 に答える 5

2

PointSearchHelperテーブルを変更して、x、y座標ではなくインデックスのみを使用するようにします。

create table PointSearchHelper . . .
    points_id int not null primary key

結合を行うときは、代わりにpoints_idで行ってください。これにより、スペースが削減され、パフォーマンスが向上します。

PS。私は最も奇妙な問題を抱えています。コードにオープンパレンを追加すると、回答の読み込み中にエラーが発生します。

于 2012-08-30T18:36:13.923 に答える
1

X + Yペアはユニークですか?
そうである場合は、ID列を削除し、X+Yペアに複合主キーを作成することを検討してください。これにより、追加のインデックスが不要になり、クエリがさらに高速化される可能性があります。

于 2012-08-30T18:12:18.523 に答える
1

これは、このテーブルに対する他のクエリに大きく依存しますが、完全なインデックスが必要ない場合は、IDから主キーを削除し、代わりに主キー(およびクラスター化インデックス)を(X, Y)

これを行うと、データがX値とY値でテーブルに格納されるため、この特定のクエリはより高速になり、新しく作成されたクラスター化インデックスのみを使用する必要があります。

PointsID in句を使用するテーブルに対するクエリがある場合WHERE、この列は現在のようにソートされたASCに格納されなくなるため、パフォーマンスに関する潜在的な問題を探す必要があります。クエリの大部分がX、Y値でこのテーブルをクエリしていることがわかった場合は、開発サーバーでこの変更をテストして、ニーズに合っているかどうかを確認できます。

于 2012-08-30T18:12:47.867 に答える
1

キー以外の値を含めずにインデックスを作成すると、どのような結果が得られますか?フルインデックスで得られる速度に近い場合があります。

さらに、X、Y座標がポイントで一意であることが保証されている場合は、ID列を削除し、(X、Y)に直接主キーを作成することを検討できます。これにより、スペースが節約され、その列のインデックス作成のオーバーヘッドも節約されます。

于 2012-08-30T18:14:26.130 に答える
0

私は「宿題」を作ったので、ここで答えるのは簡単だと思います。驚いたのは次のとおりです。

初め:

INCLUEDED非キー値なしでINDEXを変更する->役に立たない、フルインデックスなしの通常のパフォーマンスと同様に、パフォーマンスは約280ミリ秒です。

2番:

ID列を削除してX +Yを主キーにし(これらのポイントが一意であるとしましょう)、X+YのPointSearchHelperテーブルに他の主キーインデックスを作成します。そのソリューションは私を驚かせました。実行プランは両方のインデックスを使用していましたが、速度も約280ミリ秒でした。だからそれはまったく役に立たなかった

第3:

XとYを格納するIDを削除します。たとえば、値を保存するときにその周りにロジックを作成して、それらのレコードの主キーIDを確認します。これにより、インデックスは2つだけになり、PointsとPointHelperSearchには2つの主キーインデックスがあります。(実行計画で両方を見ることができます、それらは使用されます。)そしてそれはそれをしました!! 速度は約60〜70ミリ秒でした。だからここにトリックがあります。

さて、 2番目3番目の違いは何だろうと思います。それは非常に多くのミリ秒を数えるので、1つではなく2つの数がありますか?

于 2012-08-31T05:44:02.927 に答える