MySql データベースに基づいて PyQT ソフトウェアを開発しています。データベースには、いくつかの記録された電気信号と、これらの信号を説明するすべての情報 (サンプリング レート、記録の日付など...) が含まれています。
アイデアを得るために、1 つのデータベースに 10,000 ~ 100,000 行が含まれ、合計サイズが 10Gb を超えるとします。これらのデータはすべて専用サーバーに保存されます。実際、ほとんどのデータは信号自体であり、analogsignal.signal という BLOB フィールドにあります (以下を参照)。
データベースのアーキテクチャは次のとおりです: http://packages.python.org/OpenElectrophy/_images/simple_diagram1.png
変更できません (列とインデックスを追加できますが、既存の列を移動または削除することはできません)。
ソフトウェアでは、analogsignal.id を介して後で呼び出される analogsignal.signal を除いて、すべての analogsignal 列 (id、名前、チャネル、t_start、sampling_rate) をリストする必要があります。だから私は次のクエリをやっています
SELECT block.id、block.datetime、segment.id、analogsignal.id、analogsignal.name、analogsignal.channel、analogsignal.sampling_rate、block.fileOrigin、block.info
FROM セグメント、ブロック、アナログ信号
WHERE block.id=segment.id_block
AND segment.id=analogsignal.id_segment
ORDER BY analogsignal.id
問題は、analogsignal.signal 列が存在するため、クエリが非常に遅いことです (リクエストがキャッシュにない場合は 10 分以上)。何が起こっているのかを正しく理解していれば、analogsignal.signal が SELECT フィールドにない場合でも、analogsignal.signal を含むテーブルが 1 行ずつ読み取られます。
BLOBを他のテーブルに移動せずにデータベースまたはクエリを最適化する方法を知っている人はいますか(これはより論理的であることに同意しますが、この点は制御しません)。
ありがとうございました!
これは、AnalogSignal テーブルの CREATE TABLE コマンドです (コメントからプル/フォーマットされています)。
CREATE TABLE analogsignal
( id int(11) NOT NULL AUTO_INCREMENT,
id_segment int(11) DEFAULT NULL,
id_recordingpoint int(11) DEFAULT NULL,
name text,
channel int(11) DEFAULT NULL,
t_start float DEFAULT NULL,
sampling_rate float DEFAULT NULL,
signal_shape varchar(128) DEFAULT NULL,
signal_dtype varchar(128) DEFAULT NULL,
signal_blob longblob, Tag text,
PRIMARY KEY (id),
KEY ix_analogsignal_id_recordingpoint (id_recordingpoint),
KEY ix_analogsignal_id_segment (id_segment)
) ENGINE=MyISAM AUTO_INCREMENT=34798 DEFAULT CHARSET=latin1 ;
編集:問題は解決しました。重要な点は次のとおりです。
-アナログ信号テーブルのすべての SELECT フィールドに複数列インデックス、タイプ INDEX を追加する必要がありました
。 - 「TEXT」タイプの列がインデックスの使用をブロックしていました。これらの TEXT フィールドを VARCHAR(xx) に変換しました。このために、次の簡単なコマンドを使用しました。
SELECT MAX(LENGTH(field_to_query)) FROM table_to_query
変換前に最小テキスト長をチェックして、データが失われないことを確認する
ALTER TABLE table_to_query CHANGE field_to_query field_to_query VARCHAR(24)
最初は VARCHAR(8000) を使っていたのですが、この設定だと VARCHAR が TEXT フィールドみたいになり、インデックスが効かなくなりました。VARCHAR(24) ではそのような問題はありません。私が正しければ、クエリの TEXT の合計長 (すべてのフィールドを含む) は 1000 バイトを超えてはなりません
次に、上記のようにすべての列にインデックスを付けました。インデックスにサイズパラメーターはありません
最後に、より優れたクエリ構造を使用して (DRapp に感謝)、クエリも改善されました。キャッシュなしで、クエリの 215 秒から 0.016 秒に渡しました...