4

私は大きな MySQL テーブルを持っていますが、適切にインデックスが作成されていても、クエリごとに 1 秒かかる場合があります (あまり聞こえませんが、何千ものサーバーで実行されます)。現在、4 つのクエリを実行して、95 パーセンタイルのインバウンド、95 パーセンタイルのアウトバウンド、および両方の合計を取得しています。

クエリ 1: 95 パーセンタイル行を取得するための行数を取得するには

SELECT round(count(*)*.95 FROM traffic WHERE server_id = 1;

クエリ 2&3 95 パーセンタイルを取得するには

SELECT inbound FROM traffic WHERE server_id = 1 ORDER BY inbound ASC LIMIT {95th},1
SELECT outbound FROM traffic WHERE server_id = 1 ORDER BY outbound ASC LIMIT {95th},1

クエリ 4 トラフィックの合計を取得する

SELECT sum(inbound+outbound) FROM traffic WHERE server_id = 1; 

これらを組み合わせる方法を考えてみませんか?カウントに基づいて特定の行を選択することによって計算される 95 パーセンタイルを取得する必要があるため、方法を考えることに挑戦しています。たとえば、10000行ある場合、昇順に並べ替えて9500行目を選択します。

4

2 に答える 2

3

ある程度の精度を犠牲にしても構わないと思っている場合は、正確な行数ではなく行数の見積もりを使用できます。データベースが InnoDB を使用している場合、SELECT count(*)非常に遅くなる可能性があります。言い換えると:

  1. 見積もりを取得するには、コマンドを使用できますSHOW TABLE STATUS。電光石火の速さですが、必ずしも 100% 正確というわけではありません。

  2. ステートメントを置き換えます。

    SELECT inbound FROM traffic WHERE server_id = 1 ORDER BY inbound ASC LIMIT {95th},1
    

    SELECT inbound FROM traffic WHERE server_id = 1 ORDER BY inbound DESC LIMIT {5th},1
    

    結果は同じはずですが、約 20 倍高速です。に複合インデックスを作成するようにして(server_id, inbound)ください。

  3. 2を参照してください。

  4. これは放っておきましょう。

必要な数を取得するための合計時間が数ミリ秒に短縮されることを期待しています。

于 2013-10-25T03:47:33.013 に答える
2

http://planet.mysql.com/entry/?id=13588に記載されているとおり:

SELECT
    SUBSTRING_INDEX(
            SUBSTRING_INDEX(
                GROUP_CONCAT( 
                    t.inbound
                    ORDER BY t.inbound
                    SEPARATOR ','
                )
            ,   ','
            ,   95/100 * COUNT(*) + 1
            )
        ,   ','  
        ,   -1  
        )                 AS `Inbound95`
    ,
    SUBSTRING_INDEX(
            SUBSTRING_INDEX(
                GROUP_CONCAT(  
                    t.outbound
                    ORDER BY t.outbound
                    SEPARATOR ','
                )
            ,   ','         
            ,   95/100 * COUNT(*) + 1 
            )
        ,   ','                       
        ,   -1                          
        )                 AS `Outbound95`
FROM   traffic AS t WHERE t.server_id = 1

2つのパーセンタイルが表示されます

注: 増やす必要がある場合がありますgroup_concat_max_len

于 2013-10-25T03:46:22.640 に答える