Hi, Eugene!

I suspect that you have run into locking issues with your table, which I am guessing is a MyISAM table. MyISAM provides only table-level locking - that is, only one write operation can occur at any time on the table. Other operations are blocked until their turn comes.


It appears you have about 10 threads or processes running against this table, which is enough to introduce performance problems.

Some suggestions:

1 - while your current select query is reasonably fast, it likely could be faster. It's using an indexed column (status), but it's not a very good index (no offense). There are only a few possible values, so the index isn't terribly helpful in locating matching records. If possible, you could re-write your perl scripts to do selects and updates against the ID column (primary key), which should be much faster. This may be enough to alleviate your locking problem; not sure.

2 -

Eugene Kosov wrote:
Hi, list!

I have a little table (about 0.5 milloin records) which is kind of queue. My perl script takes records from it one by one and does somes actions.

Here's my table structure:

mysql> desc queue;
+----------------------+---------------------+------+-----+-------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------------+---------------------+------+-----+-------------------+----------------+ | id | int(10) unsigned | | PRI | NULL | auto_increment | | status | tinyint(4) | | MUL | 0 | | | processor_id | int(10) unsigned | YES | MUL | NULL | |
... some other data ...
+----------------------+---------------------+------+-----+-------------------+----------------+



This table, of course, has some indecies:

mysql> show indexes from queue;
+--------------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+ | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | +--------------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+ | queue | 0 | PRIMARY | 1 | id | A | 522756 | NULL | NULL | | BTREE | | | queue | 1 | status | 1 | status | A | 3 | NULL | NULL | | BTREE | | | queue | 1 | processor_id | 1 | processor_id | A | 522756 | NULL | NULL | YES | BTREE | | +--------------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+
3 rows in set (0.00 sec)



Perl scripts runs a query like 'UPDATE queue SET status=1, processor_id=XXX WHERE status=0 LIMIT 1'. Whis query shoud (and uses as we can see in following EXPLAIN result) `status` index and work rather fast. But.. It becomes slower and slower. I don't understand why.


mysql> explain select * from certificates where status=0;
+----+-------------+--------------+------+---------------+--------+---------+-------+-------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------------+------+---------------+--------+---------+-------+-------+-------------+ | 1 | SIMPLE | queue | ref | status | status | 1 | const | 52740 | Using where | +----+-------------+--------------+------+---------------+--------+---------+-------+-------+-------------+
1 row in set (0.00 sec)


Despite row numbers to scan (in EXPLAIN results) I think query should work fast because of 'LIMIT 1'. And it works. A query like 'SELECT * FROM queue WHERE status=0 LIMIT 1' works very fast. But in case of update I see that it's not so fast.

mysql> show processlist;
+------+------+-----------+--------------+---------+------+---------------------------+---------------------------------------------------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +------+------+-----------+--------------+---------+------+---------------------------+---------------------------------------------------------------------------------------+ | 3257 | root | localhost | certificates | Sleep | 247 | | NULL | | 3261 | root | localhost | certificates | Query | 0 | Locked | SELECT id, domain FROM queue WHERE status='1' AND processor_id='10580' LIMIT 1 | | 3262 | root | localhost | certificates | Query | 1 | Locked | UPDATE queue SET status='1', processor_id='10584' WHERE status='0' LIMIT 1 | | 3263 | root | localhost | certificates | Query | 1 | Locked | SELECT id, domain FROM queue WHERE status='1' AND processor_id='10588' LIMIT 1 | | 3264 | root | localhost | certificates | Query | 1 | Locked | SELECT id, domain FROM queue WHERE status='1' AND processor_id='10590' LIMIT 1 | | 3265 | root | localhost | certificates | Query | 1 | Locked | UPDATE queue SET status='1', processor_id='10592' WHERE status='0' LIMIT 1 | | 3266 | root | localhost | certificates | Query | 1 | Locked | UPDATE queue SET status='1', processor_id='10604' WHERE status='0' LIMIT 1 | | 3267 | root | localhost | certificates | Query | 1 | Locked | UPDATE queue SET status='1', processor_id='10614' WHERE status='0' LIMIT 1 | | 3268 | root | localhost | certificates | Query | 1 | Searching rows for update | UPDATE queue SET status='1', processor_id='10616' WHERE status='0' LIMIT 1 | | 3269 | root | localhost | certificates | Query | 1 | Locked | UPDATE queue SET status='1', processor_id='10618' WHERE status='0' LIMIT 1 | | 3270 | root | localhost | certificates | Query | 1 | Locked | UPDATE queue SET status='1', processor_id='10620' WHERE status='0' LIMIT 1 | | 3271 | root | localhost | certificates | Query | 0 | NULL | show processlist | +------+------+-----------+--------------+---------+------+---------------------------+---------------------------------------------------------------------------------------+
12 rows in set (0.00 sec)

Is it because of index changing after update?
Am I doing something wrong?
Any ideas about how to improve perfomance of this?

Thanks in advance!!


P.S: Size of index is about 10M so it can be loaded into buffer entirely.
mysql> show variables like '%key%';
+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| delay_key_write          | ON         |
| have_rtree_keys          | YES        |
| key_buffer_size          | 20971520   |
| key_cache_age_threshold  | 300        |
| key_cache_block_size     | 1024       |
| key_cache_division_limit | 100        |
| max_seeks_for_key        | 4294967295 |
+--------------------------+------------+
7 rows in set (0.00 sec)







--
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:    http://lists.mysql.com/[EMAIL PROTECTED]

Reply via email to