2

基本的に、私は約7億行で構成されるテーブルを持っており、1日あたり約20万から30万行で絶えず更新されており、毎月月末に3か月以上前のデータを消去します。

CREATE TABLE TESTRECORD (
  TIMEADDED timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  SERIAL varchar(8) NOT NULL,
  ENDTIME varchar(14) NOT NULL,
  MODEL varchar(2) NOT NULL,
  PROCESS int(4) NOT NULL,
  PF varchar(4) NOT NULL,
  COMID varchar(6) NOT NULL,
  COMTP varchar(3) NOT NULL,
  TRIAL varchar(4) NOT NULL,
  TEST varchar(8) NOT NULL,
  SECTION int(2) NOT NULL,
  DATA_0 float NOT NULL,
  DATA_1 float NOT NULL,
  DATA_2 float NOT NULL,
  DATA_3 float NOT NULL,
  DATA_4 float NOT NULL,
  DATA_5 float NOT NULL,
  PRIMARY KEY (SN,ENDTIME,SECTION),
  UNIQUE KEY BASESN (SN,ENDTIME,MODEL,PROCESS,PF,COMID,TRIAL,TEST,SECTION),
  KEY COMID (COMID),
  KEY TRIAL (TRIAL),
  KEY PF (PF),
  KEY TEST (TEST)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

一意キーは、selectステートメントで使用されるパラメーターを定義しました。このテーブルの基本的な機能は動的データ分析であるため、where句で何が発生し、それらがいくつ使用されるかについての特定の順序はなく、1つまたは2つの列によるランダムなグループ化が存在する可能性があります。一意のキーからも。したがって、すべての可能なコンボにインデックスを付けて、特定の選択での高速操作を保証することはほとんど不可能です。

私の理解では、mysqlはスキーマにリストされている順序に基づいてインデックスを使用するため、私の場合、selectステートメントでSN、ENDTIME、およびPFを使用すると、一意のキーから最初の2列のみが使用されます。列ごとに1つのインデックスのようにインデックスを分割したり、クエリ手法を使用して処理を少し高速化したり、少なくともwhere句のさまざまな列の組み合わせでほぼ同等のパフォーマンスを実現したりする効率的な方法はありますか?

よろしくお願いします〜!!!

4

3 に答える 3

2

MySQLのインデックスは、本の最後にあるインデックスのように機能します。「ペパロニピザ」の料理本を探している場合は、最初にペパロニを検索し、次にピザを検索します。「ピザ」だけを探している場合、ピザはインデックス内のペパロニに次ぐものであるため、そのインデックスは役に立ちません。最初にペパロニを検索した場合にのみピザを見つけることができます。これが、列X、Yのインデックスが機能する方法です。列Xと列Yでこの順序でクエリを実行することを計画している場合は、2つの列のインデックスを一緒に使用する方が理にかなっています。Xでクエリを実行し、Yでクエリを実行する場合、複合インデックスはあまり役に立ちません。

座って、最も頻繁に実行するクエリの種類を定義し、ストレージと処理能力を分析することをお勧めします。インデックスは、特に数百万行で作業する場合、多くのスペースを占める可能性があります。インデックスは、ストレージスペースと処理能力の間の典型的なトレードオフであり、データベースに精通していない人は、特定の状況に最適なインデックスの数または構成を教えてくれません。

各列に格納されている一意の値の数も確認してください。MySQLは、Oracleとは異なり、標準テーブルのビットマップスタイルのインデックスをサポートしていません(Bツリーを使用します)。技術的な詳細はさておき、これは、一意の値の数が比較的少ない列にインデックスを作成しても、インデックススペースの単位あたりの値が思ったほど多くないことを意味します。

最後の注意点は、特定のタイプのデータ分析では、データの一部をMEMORYテーブルにエクスポートすることを検討することをお勧めします。MEMORYテーブルは基本的に一時的なテーブルであり、ユーザーセッション間で構造を保存します。それらはデータを失いますが、使用を終えたときやクラッシュが発生した場合は構造は失われません。メモリテーブルは、インデックス付きの列の値をハッシュしてデータの取得を高速化するHASHインデックスをサポートします。ほとんどの場合、これらは非常に高速であり、正しく使用するとパフォーマンスを劇的に向上させることができます。

DBの最適化に本当に興味がある場合は、「HighPerformanceMySQL」という本を参照することをお勧めします。

于 2012-04-17T19:22:30.850 に答える
1

たとえば、infobrightオープンソース分析データベースのような列ベースのストレージエンジンなど、別のストレージを検討することをお勧めします。これはmysqlアーキテクチャに基づいており、ビッグデータと分析クエリを対象としていることを除けば、mysqlでの作業とまったく同じです。www.infobright.org

于 2012-04-17T19:17:17.847 に答える
0

任意のテーブルのソリューション:

SELECT 
  CONCAT(
    'ALTER TABLE ', 
    TABLE_NAME, 
    ' ', 
    'ADD ', 
    IF(
      NON_UNIQUE = 1, 
      CASE UPPER(INDEX_TYPE) WHEN 'FULLTEXT' THEN 'FULLTEXT INDEX' WHEN 'SPATIAL' THEN 'SPATIAL INDEX' ELSE CONCAT(
        'INDEX ', INDEX_NAME, ' USING ', INDEX_TYPE
      ) END, 
      IF(
        UPPER(INDEX_NAME) = 'PRIMARY', 
        CONCAT(
          'PRIMARY KEY USING ', INDEX_TYPE
        ), 
        CONCAT(
          'UNIQUE INDEX ', INDEX_NAME, ' USING ', 
          INDEX_TYPE
        )
      )
    ), 
    '(', 
    GROUP_CONCAT(
      DISTINCT CONCAT('', COLUMN_NAME, '') 
      ORDER BY 
        SEQ_IN_INDEX ASC SEPARATOR ', '
    ), 
    ');'
  ) AS 'Show_Add_Indexes' 
FROM 
  information_schema.STATISTICS 
WHERE 
  TABLE_SCHEMA = 'your_database' 
  and TABLE_NAME = 'your_table';
-- GROUP BY 
--   TABLE_NAME, 
--   INDEX_NAME 
-- ORDER BY 
--   TABLE_NAME ASC, 
--   INDEX_NAME ASC;
于 2021-02-05T12:44:23.757 に答える