私たちは、効果的なインデックスと主キーを作成する方法がほとんどないことを発見した、特に挑戦的で非常に大きなデータセットでしばらく実験してきました (経済的な選択肢ではないデータベースの完全に根本的な再設計を除けば)この時点で)。クエリまたはテーブル構造 (パーティショニングなど) を変更する方法についての提案を探しています。要するに、非常に時間がかかるデカルト結合になってしまいます。
これが核心です:
ここに 3 つの主要なサンプル テーブルがありますが、これらの結果と同様に 2 ~ 3 を結合することがあります。
(??) を指定した場合、頭を悩ませています (これは本当にこれを設定する最良の方法でしたか? チャイムインしてください)
samples - すべてのサンプル ケースの人口統計を処理するメインのテーブル フィールド:
- sampleid (PK ではなく UNIQUE ??) varchar (255) - ほとんどのデータは 10 桁の整数 (??) です。これは、特定のレポートのデータベース全体で一意の ID です。
- case - varchar (255) - ほとんどが 10 ~ 12 桁の整数 (??) です。これは一意の ID の 2 番目の形式ですが、1000001 のケース値には、他のテーブルで 1 ~ 20 のサンプル ID が関連付けられている場合があります (後で詳しく説明します)。 ) シーケンシャル/時系列の情報を提供します。(日記みたいな)
adj_samples
サンプル以外の拡張/注釈付きデータが含まれ、SampleID によってサンプルにリンクされます
田畑:
RecordID (PK) レコード (??) をカウントする autonum です。
1 つのサンプル id のサンプルテーブルにリンクされている SampleID -> 多くの adj_case レコードにリンクされています。サンプルには、 adj_caseテーブルの目的であるいくつかの注釈メモ、またはそれに関連付けられているその他の詳細がある場合があります。
ProbableID - int、単なる内部コード情報コード。
結果 フィールド:
- SampleID varchar 255 (これもおそらく int の可能性があります)
- 結果 (私が見たものから、100 len char フィールドに制限されていますが、フィールド len は 255 varchar に設定されています)
基本的に、SampleID one DISTINCT(SampleID) によって adj_samples にリンクされ、多くの結果、結果フィールドは他よりも詳細なさまざまなレベルの情報を示します。
テーブルサイズ
samples 2,946,614 rows, MyISAM - 384MB
adj_samples 12,098,910 rows, myISAM, 1.3 GB
result 13,011,880 rows 428,508 KB
サンプル クエリは、特定の内部 ID (probableID) のすべてのケース カウントを提供するものです。
SELECT r.result as result
, COUNT(DISTINCT p.`case`) as ResultCount
FROM Adj_Samples as
LEFT JOIN samples s
ON as.SampleID = s.SampleID
LEFT JOIN results r
ON as.SampleID = r.SampleID
WHERE ProbableID = '101'
AND ProbableID NOT IN #(subquery to table of banned codes we dont want to see)
GROUP BY r.result
ORDER BY COUNT(DISTINCT p.`case`)
関連情報を含む他のテーブルがあるため、後で結果に似たいくつかのテーブルに参加する必要がある場合があります.5〜6が積み重なっていて、完全にデカルトになることは珍しくありません. 最善を尽くしてインデックスを作成しましたが、キーになる可能性のある非常に多くの varchar を扱っています (results.result はインデックスですが、100 ~ 255 文字の長さです!)。
サンプルの奇妙な未使用フィールドが PK であることに疑問があります。SampleID は一意であるはずなので PK であるべきだと思われますが、エラーによって重複が発生した可能性がありますか?
私はパーティショニング戦略のようなものを探しており、一般的にこれを実現するために箱の外で考えています。この情報には、中間インデックス テーブルとして使用する数値コードと 1 対 1 のテーブルの方法があまりありません。
ここに私の my.cnf があります。パフォーマンスに大きな問題があるため、参考になる場合は、ボックスは 16 GB の RAM を搭載した 8 コアの Intel 専用 centos5.5 です。これらの大規模な結合では、多くの場合、ディスクに書き込む必要があることがわかりました。繰り返しますが、最初に対処する必要があると思うのは、保存しているデータの適切なフィールドサイズです。10 桁の整数の var 255 は無駄のようです
実際に必要な長さを超える過剰なフィールド長は、テーブル サイズによってパフォーマンスに影響しますか?
dbスキーマの画像も添付されています
説明付き: 私は説明の最初の Adj_Samples で本当に弾丸をかみます - それは Using where; に行きます。一時的な使用; Filesort を使用してから別の where on を使用すると、4 行で where を使用します。すべて ref 型です。
ここにいくつかの my.cnf があります:
[mysqld]
socket = /var/lib/mysql/mysql.sock
key_buffer = 2048MB
max_allowed_packet = 16MB
group_concat_max_len = 16MB
table_cache = 1024MB
sort_buffer_size = 4MB
read_buffer_size = 4MB
read_rnd_buffer_size = 16MB
myisam_sort_buffer_size = 128MB
thread_cache_size = 16
thread_concurrency = 16
query_cache_type = 1
query_cache_size = 512MB
tmpdir = /home/tmp
join_buffer_size = 4MB
max_heap_table_size = 3GB
tmp_table_size = 512MB
log-slow-queries
long_query_time = 20
no-auto-rehash
[isamchk]
key_buffer =1024M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M
[myisamchk]
key_buffer = 4096M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M
**This part strikes me as odd as I don't believe we are using any innodb tables**
innodb_data_home_dir = /var/lib/mysql/
innodb_data_file_path = ibdata1:2000M;ibdata2:10M:autoextend
innodb_log_group_home_dir = /var/lib/mysql/
innodb_log_arch_dir = /var/lib/mysql/
innodb_buffer_pool_size = 1024M
innodb_additional_mem_pool_size = 20M
**comment form whoever:** Set .._log_file_size to 25 % of buffer pool size
innodb_log_file_size = 100M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50
皆様のご協力に感謝いたします。私は mysql を学び始めて 6 か月になり、多くのことを学びましたが、この演習で皆様からさらに多くのことを学べることを楽しみにしています。
bash の場合: トップ mysql プロセスが 30% のメモリしか使用していませんが、CPU の 200 ~ 400% でラックアウトするのは正常なことですか?