2

MySQL/MariaDB InnoDB/XtraDB で奇妙な動作が発生しています。最近、MariaDB 5.5 に切り替えました。この切り替えにより、サーバー全体のパフォーマンスが向上しましたが、まだこの問題が残っています。

1 つの特定のテーブル インデックスが時々壊れているようです。そしてしばらくすると、それは自動的に修正されます。

SHOW CREATE TABLE article_inventory;与える

CREATE TABLE `article_inventory` (
    `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
    `article_variant_id` BIGINT(20) UNSIGNED NULL DEFAULT NULL,
    `season_id` BIGINT(20) UNSIGNED NOT NULL,
    `warehouse_id` BIGINT(20) UNSIGNED NOT NULL,
    `quantity` BIGINT(20) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`),
    UNIQUE INDEX `unique_inventory_idx` (`article_variant_id`, `season_id`, `warehouse_id`),
    INDEX `article_variant_id_idx` (`article_variant_id`),
    INDEX `article_inventory_season_id_idx` (`season_id`),
    INDEX `article_inventory_warehouse_id_idx` (`warehouse_id`),
    CONSTRAINT `article_inventory_article_variant_id_article_variant_id` FOREIGN KEY (`article_variant_id`) REFERENCES `article_variant` (`id`),
    CONSTRAINT `article_inventory_season_id_season_id` FOREIGN KEY (`season_id`) REFERENCES `season` (`id`),
    CONSTRAINT `article_inventory_warehouse_id_warehouse_id` FOREIGN KEY (`warehouse_id`) REFERENCES `warehouse` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=3827622858;

編集: SELECT クエリの大部分は、このテーブルに対して行われます。大きな更新は 1 時間ごとに行われます。時々非常に大規模な更新。

このクエリの実行:

SELECT a.id
FROM article a
    INNER JOIN article_variant a2 
        ON a.style_id = a2.style_id
    INNER JOIN article_block a3 
        ON a2.po = a3.po
    INNER JOIN color c 
        ON a2.color_id = c.id
    INNER JOIN size s 
        ON a2.size_id = s.id
    INNER JOIN article_group a4 
        ON a2.id = a4.article_variant_id AND (a4.season_id = 6)
    INNER JOIN article_inventory a5 
        ON a2.id = a5.article_variant_id AND (((a5.warehouse_id = 5 OR a5.warehouse_id = 1) AND a5.season_id = 6))
    INNER JOIN article_date a6 
        ON a.style_id = a6.style_id AND ((a6.pricelist_id = 5 AND a6.season_id = 6))
    INNER JOIN article_price a7 
        ON a.style_id = a7.style_id AND ((a7.pricelist_id = 5 AND a7.season_id = 6))
    INNER JOIN pricelist p 
        ON a7.pricelist_id = p.id
    INNER JOIN concept c2 
        ON a4.concept_id = c2.id
    INNER JOIN category c3 
        ON a4.category_id = c3.id
    LEFT JOIN order_cart_row o 
        ON a2.id = o.article_variant_id AND (o.order_id = 17035)
    LEFT JOIN shortlist s2 
        ON a.id = s2.article_id AND (s2.order_id = 17035)
WHERE ((a2.is_canceled <> 1 AND a4.is_canceled <> 1) OR o.quantity IS NOT NULL) AND c2.id = 2
GROUP BY a.id

... 約 0.5 ~ 1.0 秒で実行され、次のような説明が表示されます。

id select_type table  type     possible_keys                                                                                               key                                 key_len    ref                                  rowsExtra
1  SIMPLE      p      const    PRIMARY                                                                                                     PRIMARY                             8          const                                1   Using index; Using temporary; Using filesort
1  SIMPLE      c2     const    PRIMARY                                                                                                     PRIMARY                             8          const                                1   Using index                            
1  SIMPLE      a3     index    PRIMARY                                                                                                     PRIMARY                             98         NULL                                 1031Using where                            
1  SIMPLE      a2     ref      PRIMARY,unique_variant_idx,color_id_idx,style_id_idx,size_id_idx,article_variant_po_idx                     article_variant_po_idx              98         wsp_stage.a3.po                      14  Using where                            
1  SIMPLE      s      eq_ref   PRIMARY                                                                                                     PRIMARY                             11         wsp_stage.a2.size_id                 1   Using index                            
1  SIMPLE      c      eq_ref   PRIMARY                                                                                                     PRIMARY                             11         wsp_stage.a2.color_id                1                                          
1  SIMPLE      o      eq_ref   unique_rows_idx,article_variant_id_idx,order_id_idx                                                         unique_rows_idx                     16         const,wsp_stage.a2.id                1   Using index                            
1  SIMPLE      a      eq_ref   unique_style_idx                                                                                            unique_style_idx                    767        wsp_stage.a2.style_id                1   Using index                            
1  SIMPLE      a6     ref      article_season_pricelist_unique_idx,season_id_idx,pricelist_id_idx,style_id_idx                             article_season_pricelist_unique_idx 784        wsp_stage.a2.style_id,const,const    1   Using index                            
1  SIMPLE      a7     ref      article_season_pricelist_unique_idx,season_id_idx,pricelist_id_idx,style_id_idx                             article_season_pricelist_unique_idx 784        wsp_stage.a2.style_id,const,const    1   Using index                            
1  SIMPLE      a4     eq_ref   unique_group_idx,one_per_season_idx,category_id_idx,concept_id_idx,season_id_idx,article_variant_id_idx     one_per_season_idx                  16         wsp_stage.a2.id,const                1   Using index                            
1  SIMPLE      c3     eq_ref   PRIMARY                                                                                                     PRIMARY                             8          wsp_stage.a4.category_id             1   Using index                            
1  SIMPLE      s2     ref      shortlist_article_id_idx                                                                                    shortlist_article_id_idx            8          wsp_stage.a.id                       10  Using where                            
1  SIMPLE      a5     ref      unique_inventory_idx,article_variant_id_idx,article_inventory_season_id_idx,article_inventory_warehouse_id_iunique_inventory_idx                17         wsp_stage.a2.id,const                8   Using where 

すべてが正常に機能している場合、article_inventory (エイリアス a5) はunique_inventory_idx、またはを使用しarticle_variant_id_idxます。両方とも、約 5 ~ 100 行の検査結果が得られるはずです。

しかし、時々何かが起こり、同じクエリに最大で約 30 秒かかり、次のように説明されます。

id select_type table  type     possible_keys                                                                                               key                                 key_len  ref                                  rows    Extra
1  SIMPLE      p      const    PRIMARY                                                                                                     PRIMARY                             8        const                                1       Using index; Using temporary; Using filesort
1  SIMPLE      c2     const    PRIMARY                                                                                                     PRIMARY                             8        const                                1       Using index
1  SIMPLE      a5     ref      unique_inventory_idx,article_variant_id_idx,article_inventory_season_id_idx,article_inventory_warehouse_id_iarticle_inventory_season_id_idx     8        const                                6718732 Using where
1  SIMPLE      a4     eq_ref   unique_group_idx,one_per_season_idx,category_id_idx,concept_id_idx,season_id_idx,article_variant_id_idx     one_per_season_idx                  16       wsp_stage.a5.article_variant_id,const1       Using where
1  SIMPLE      c3     eq_ref   PRIMARY                                                                                                     PRIMARY                             8        wsp_stage.a4.category_id             1       Using index
1  SIMPLE      a2     eq_ref   PRIMARY,unique_variant_idx,color_id_idx,style_id_idx,size_id_idx,article_variant_po_idx                     PRIMARY                             8        wsp_stage.a5.article_variant_id      1       
1  SIMPLE      c      eq_ref   PRIMARY                                                                                                     PRIMARY                             11       wsp_stage.a2.color_id                1       Using index
1  SIMPLE      a      eq_ref   unique_style_idx                                                                                            unique_style_idx                    767      wsp_stage.a2.style_id                1       Using index
1  SIMPLE      a6     ref      article_season_pricelist_unique_idx,season_id_idx,pricelist_id_idx,style_id_idx                             article_season_pricelist_unique_idx 784      wsp_stage.a2.style_id,const,const    1       Using index
1  SIMPLE      a7     ref      article_season_pricelist_unique_idx,season_id_idx,pricelist_id_idx,style_id_idx                             article_season_pricelist_unique_idx 784      wsp_stage.a2.style_id,const,const    1       Using index
1  SIMPLE      s      eq_ref   PRIMARY                                                                                                     PRIMARY                             11       wsp_stage.a2.size_id                 1       Using index
1  SIMPLE      a3     eq_ref   PRIMARY                                                                                                     PRIMARY                             98       wsp_stage.a2.po                      1       Using index
1  SIMPLE      o      eq_ref   unique_rows_idx,article_variant_id_idx,order_id_idx                                                         unique_rows_idx                     16       const,wsp_stage.a5.article_variant_id1       Using where
1  SIMPLE      s2     ref      shortlist_article_id_idx                                                                                    shortlist_article_id_idx            8        wsp_stage.a.id                       7       Using where

article_inventory(a5) を使用してarticle_inventory_season_id_idxいます。すべてのインデックスの中で 2 番目に固有性が低いため、非常に悪いインデックスです。私に6718732の検査された行を与えます。

my.ini:

[mysqld]
datadir="W:/mariadb/data/"
port=3306
sql_mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION"
default_storage_engine=innodb
innodb_buffer_pool_size=5000M
innodb_log_file_size=52428800
innodb_file_per_table
innodb_file_format=Barracuda

[client]
port=3307
4

1 に答える 1

1

まず、インデックスは壊れていません。これはおそらく、クエリオプティマイザに間違ったインデックスを使用することを示唆しているテーブルのMySQL統計に関連しています。考えられる解決策に移る前に、まず何が原因であるかを理解しましょう。

MySQLがクエリを実行すると、そのテーブルの統計を調べて、クエリに適切なインデックスを決定し、推奨事項に基づいて正しいインデックスを選択します。テーブル統計には、インデックスのカーディナリティやインデックスの使用に関連するコストなどの情報が含まれています。MySQLは、クエリを実行するたびにこれらの統計を調べて、最適な実行パスを決定します。

インデックスは、更新時にディスクに保存される実際のデータ構造であるため、これらのインデックスに挿入および削除すると、統計が変更されます。これが問題の根本的な原因である可能性があります。InnoDBは、インデックス構造を8回ランダムに深く掘り下げることで、その場で統計を更新します。MyISAMはそれを別の方法で行います。これに関する詳細については、次のリンクを参照してください:https ://dba.stackexchange.com/questions/3398/from-where-does-the-mysql-query-optimizer-read-index-statistics

たまに重複更新で大規模な挿入を行うとおっしゃいました。挿入中または挿入後のいずれかに、テーブルのinnodb統計が古くなっているかコンパイルされている小さな期間があると思われます。これが、あるインデックスから感染性のインデックスへの散発的な変化が見られる理由かもしれません。その時点で統計が正しくなく、クエリオプティマイザが間違った選択をしています。

次のグーグルに行きます:

mysql statistics update

これについての詳細を含むリンクのスタック全体があり、それはいくつかの良い読み物です。

これはデータベースで以前に発生したことがありますが、これはバグではなく、注意する必要があるものです。

可能な解決策:

  1. 重複した更新ステートメントを使用して一括挿入した後、問題のテーブルでANALYZETABLEを明示的に呼び出します。更新の直後にこのコマンドを実行すると、統計が正しい形式になる可能性があるため、適切なインデックスが提案されます。欠点は、システムが実際に統計を2回再コンパイルしている可能性があることです。これは、リソースを浪費するようなものです。この問題が挿入ステートメントの後で発生するのか、それとも挿入ステートメントの最中に発生するのかわからないことを覚えておいてください。
  2. selectステートメントで正しいインデックスの使用を強制します。MySQLに常に正しいインデックスを使用させることができます。ただし、これは悪い考えです。ある時点で、別のインデックスがクエリに対してより最適化される可能性があります。現在、クエリで使用するインデックスを効果的にハードコーディングしているため、後で問題になります。
  3. そのままにしておくと、奇妙に聞こえるかもしれませんが、クエリが30秒間実行されるのは災害ですか?要件によって異なる場合がありますが、クエリの実行に30秒で問題がない場合は、なぜそれを修正してみてください。それが壊れていない場合は、哲学を修正しないでください。

さらに明確にする必要がある場合は、コメントを投稿するのが理にかなっていると思います。

于 2013-02-12T08:23:22.317 に答える