SQLiteデータベースから読み込むために動的に構築されたクエリを使用する複雑なC#プログラムがあります。フィールドがテーブルの主キーである場合のSQLite "MyTable(ID)の自動インデックス"
SQLite warning (284): automatic index on MyTable(Id)
私はMyTableというのスキーマを見てきた、とIdは、主キーとして指定され、このような:
私は、デバッガの下でプログラムを実行すると、私は気づく は、私のような出力の多くを得ますCREATE TABLE MyTable (Id varchar(50) collate nocase primary key not null,
Name varchar(50) not null,
(etc)
私はSQLiteが主キーのインデックスを作ったと思っていました。それで、別のものを作るのはなぜですか?
また、関連するノートでは、サブクエリに関する自動インデックス警告が多数表示されます。たとえば、クエリに:
MyTable has Id as the primary key
Organisations has Id as the primary key
SubTable has a unique index on ArrangementId, OrganisationId
は、クエリの利回りにクエリプランをEXPLAIN
SELECT MyTable.Id, MyTable.Name, Amount
FROM MyTable
LEFT JOIN (SELECT ArrangementId, Amount, AgreementDate FROM SubTable
JOIN Organisations ON Organisations.Id = SubTable.OrganisationId AND Organisations.Direction = 1
) AS MyJoin ON MyJoin.ArrangementId = MyTable.Id
ORDER BY Id
:
1|0|0|SCAN TABLE SubTable
1|1|1|SEARCH TABLE Organisations USING INDEX sqlite_autoindex_Organisations_1 (Id=?)
0|0|0|SCAN TABLE Arrangements USING INDEX sqlite_autoindex_Arrangements_1
0|1|1|SEARCH SUBQUERY 1 AS MyJoin USING AUTOMATIC COVERING INDEX (ArrangementId=?)
私はSQLiteのサブクエリということを理解してくれないと思います一時テーブルに入る必要はありませんか?
サブクエリが回避されるようにクエリを書き直す方法はありますか?
、なぜあなたが使用しているvarchar型?これにより、列の値が2回、bツリーに1回、テーブルに1回格納されます。私は整数の主キーを使用し、別の列にテキストを格納することをお勧めします。必要に応じて、他の列に対しても一意制約を設定できます。 – seairth
テキストにユニークなインデックスを作成すると、テキストをプライマリキーとして使用するよりもスペースが少なくなりますか? –
いいえ、いずれの場合も、テキストのコピーを含むb-treeで終わります。私は、主キーとしてvarcharを使用することをより心配していました。答えでこのコメントを続ける... – seairth