2016-05-22 11 views
-1

頻繁に更新される(同じ更新クエリがループ内で実行される)このテーブルに1つの列(numviews)を持つ1つのmysqlテーブルがあります。それは2秒以上の時間がかかりますが、私はこのテーブルに依存しているアプリケーションにも影響を与えたり遅くしたりするため、これを改善する方法を見つけることができません。ここにmysqlテーブルがあります。Mysqlの更新クエリに多くの時間がかかります

注::このテーブルはinnodbであり、遅いクエリはありません。このテーブルは、mariadb galeraクラスタの下にあります。私もの最大接続数を持っています。いずれの時点においても、グローバル接続は170/180を超えません。

CREATE TABLE `data_table` (
    `site` VARCHAR(100) NOT NULL DEFAULT '', 
    `active` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', 
    `numclicks` INT(10) UNSIGNED NOT NULL DEFAULT '0', 
    `numviews` INT(20) UNSIGNED NOT NULL DEFAULT '0', 
    `country` VARCHAR(200) DEFAULT NULL, 
    `viewcount` INT(10) UNSIGNED NOT NULL DEFAULT '0', 
    `name` VARCHAR(150) NOT NULL DEFAULT '', 
    `comments` TEXT NOT NULL, 
    `boost` FLOAT DEFAULT '0', 
    `daily_limit` INT(11) DEFAULT '0', 
    PRIMARY KEY (`site`) 
) ENGINE=INNODB DEFAULT CHARSET=latin1 

、ここでループを走らMySQLの更新クエリは、(その約50倍以下のクエリは、このテーブル上で実行されます)です。

UPDATE data_table set numviews = numviews + 1 where site='xyz'; 

Query OK, 1 row affected (2.57 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 


SELECT site,active,numclicks,numviews,country,viewcount FROM data_table WHERE site='xyz'\G 
*************************** 1. ROW *************************** 
        site: xyz 
        active: 1 
       numclicks: 130406 
       numviews: 48962 
       country: |xx yy | 
       viewcount: 134022 

EDIT:私もいくつかのデッドロックを見ることができます。

------- TRX HAS BEEN WAITING 2 SEC FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 3020 page no 10 n bits 120 index `PRIMARY` of table `data_table`trx table locks 1 total table locks 47 trx id 71211631903 lock_mode X locks rec but not gap waiting lock hold time 2 wait time before grant 0 
------------------ 
---TRANSACTION 71211631885, ACTIVE 2 sec starting index read 
mysql tables in use 1, locked 1 
LOCK WAIT 2 lock struct(s), heap size 360, 1 row lock(s) 
MySQL thread id 1083597, OS thread handle 0x7f782a335700, query id 184464304 machine1 XX.XX.XX.XX user updating 
UPDATE data_table set numviews = numviews + 1 where site='xyz' 
Trx #rec lock waits 12 #table lock waits 0 
Trx total rec lock wait time 12 SEC 
Trx total table lock wait time 0 SEC 
------- TRX HAS BEEN WAITING 2 SEC FOR THIS LOCK TO BE GRANTED: 
RECORD LOCKS space id 3020 page no 10 n bits 120 index `PRIMARY` of table `data_table` trx table locks 1 total table locks 47 trx id 71211631885 lock_mode X locks rec but not gap waiting lock hold time 2 wait time before grant 0 
------------------ 
---TRANSACTION 71211631883, ACTIVE 2 sec 
mysql tables in use 1, locked 1 
2 lock struct(s), heap size 360, 1 row lock(s), undo log entries 1 
MySQL thread id 1082885, OS thread handle 0x7f713e848700, query id 184464302 xxx XX.XX.XX.XX user query end 
UPDATE data_table set numviews = numviews + 1 where site='xyz' 
Trx #rec lock waits 225 #table lock waits 0 
Trx total rec lock wait time 366 SEC 
Trx total table lock wait time 0 SEC 

このアップデートクエリを改善する方法を教えてもらえますか?

+0

テーブルにある行はありませんか? – Rahul

+0

@Rahul 1000未満 – Sthita

+0

@Strawberryはいそれはループです。私はnumviewsを1だけインクリメントしています。それはプロセスです。私は最大300の接続も持っています。いずれの時点においても、グローバル接続は170/180を超えません。 – Sthita

答えて

-1

サイトの列にインデックスが付いていることを確認するか、名前の代わりにIDでサイトを判断できるかどうかを確認してください。主キーとしてIDを作成して設定します。また、サイトが1つしかない場合は、LIMIT 1で少し改善するかもしれません。それ以外の場合はわかりません。ループ内で実行すると、PDOを使用して同じ要求を別の値で準備することができます。

+2

サイトがプライマリキーであることがわかります。したがって、デフォルトではインデックスがあります。 – Sthita

+0

あなたは正しいです、私は今作成テーブルの最後にそれを見ました。ありがとう:) – Medda86

0

これは実際には必要ありません。列を更新するか、またはnum_views列を増分することです。私が言っていることは、1000回ループしてUPDATEを実行しているとします。代わりに、set numviews = 1000 + 1(OR)という値1000を持つ単一のupdateを実行してください。つまり、手前の総ビュー数があり、次に1つのUPDATE操作を実行できる場合です。それでは以下のコードは、同じ

UPDATE data_table set numviews = total_views + 1 where site='xyz'; 
+0

あなたはUPDATEと同じだと思いませんか?numviews = numviews + 1 where site = 'xyz'; – Sthita

+0

ループを実行して、1回限りの番号を更新してください。良いRahul! – Medda86

+0

@Sthita、NO、原因はあなたが1000回ループしていて、UPDATEを実行しているからです。代わりに、 'set numviews = 1000 + 1'という1000の値で1回の更新を実行してください。 – Rahul

0

急速に変化するカウンタを行いたい場合(クリックすると、ビューは)別のテーブルにする必要があります。こうすることで、それらの列を必要としないクエリ(読み書き)がそれらの行に干渉することはありません。

これをすべてのトランザクションから削除します - それを独自のトランザクションとして行います。

Galeraノードとの距離はどのくらい離れていますか?もし彼らがクロスカントリーで、例えば100msであれば、1秒間に10回しか更新できません。それがあなたのケースである場合私のhigh speed ingestion blogを読んでください;私たちはあなたのUPDATEsのはるかに高いスループットを可能にするためにGaleraでMyISAMを使用する方法について議論することができます。

関連する問題