Optimizing MySQL, part 2

Today I wrote new tests. Today tests are targeting 3 large tables, containing from 100’000 to 1’700’000 records. We do huge number of random selects both using indexes and non-indexed ‘like’ selects. We test joins using keys and non-keys.. Well, for sure – if you do joins – you must use keys.

Test results now contain example queries and more details about measured time. What I have found are several suggestions on the following MySQL settings:

  • key_buffer_size – large value won’t help string ‘like’ selections;
  • sort_buffer_size – large value won’t help much either;
  • read_rnd_buffer_size and read_buffer_size – this does not help, when joining large tables.

Affected MySQL settings

key_buffer_size=64M
innodb_sort_buffer_size=1M
myisam_sort_buffer_size=1M
sort_buffer_size=1M
read_rnd_buffer_size=2M 
join_buffer_size=1M
read_buffer_size=2M

Best results for testing on MyISAM tables

#####################################
start global: 17:10:59
start myisam tests: 17:10:59
start get 1000 random pages myisam: 17:10:59
end get 1000 random pages myisam: 17:11:03
total get 1000 random pages myisam: 4s
start get 1000 random pages myisam: 17:11:03
end get 1000 random pages myisam: 17:11:06
total get 1000 random pages myisam: 3s
start get 1000 random pages myisam: 17:11:06
end get 1000 random pages myisam: 17:11:10
total get 1000 random pages myisam: 4s
start get 1000 random pages myisam: 17:11:10
end get 1000 random pages myisam: 17:11:14
total get 1000 random pages myisam: 4s
start get 1000 random pages myisam: 17:11:14
end get 1000 random pages myisam: 17:11:17
total get 1000 random pages myisam: 3s
Selected 5000 random records...
start myisam: SELECT using INDEX: 17:11:17
Running 5000 queries.
SQL QUERY: select * from myisam_jstats_pages where page_id=149207
end myisam: SELECT using INDEX: 17:11:18
total myisam: SELECT using INDEX: 1s
Queries per second: 5000
start myisam: SELECT using INDEX and INDEXED JOIN: 17:11:18
Running 5000 queries.
SQL QUERY: select myisam_jstats_pages.*, myisam_jstats_impressions_key.* from myisam_jstats_pages, myisam_jstats_impressions_key where myisam_jstats_pages.page_id=myisam_jstats_impressions_key.page_id and myisam_jstats_pages.page_id=149207
end myisam: SELECT using INDEX and INDEXED JOIN: 17:11:20
total myisam: SELECT using INDEX and INDEXED JOIN: 2s
Queries per second: 2500
start myisam: SELECT using INDEX and 3 INDEXED JOIN and STRING ORDER: 17:11:20
Running only 100 queries.
SQL QUERY: select myisam_jstats_pages.*, myisam_jstats_impressions_key.*, myisam_jstats_visits.*, myisam_jstats_referrer.* from myisam_jstats_pages, myisam_jstats_impressions_key, myisam_jstats_visits, myisam_jstats_referrer where myisam_jstats_pages.page_id=myisam_jstats_impressions_key.page_id and myisam_jstats_impressions_key.visit_id=myisam_jstats_visits.visit_id and myisam_jstats_referrer.visit_id=myisam_jstats_visits.visit_id and myisam_jstats_pages.page_id=73550 order by myisam_jstats_referrer.referrer
end myisam: SELECT using INDEX and 3 INDEXED JOIN and STRING ORDER: 17:11:32
total myisam: SELECT using INDEX and 3 INDEXED JOIN and STRING ORDER: 12s
Queries per second: 8.33
start myisam: SELECT using INDEX and NON-KEY JOIN, NO ORDER: 17:11:32
Running just 100 queries... NON-KEY joins are slow!
SQL QUERY: select myisam_jstats_pages.*, myisam_jstats_impressions.* from myisam_jstats_pages, myisam_jstats_impressions where myisam_jstats_pages.page_id=myisam_jstats_impressions.page_id and myisam_jstats_pages.page_id=367152
end myisam: SELECT using INDEX and NON-KEY JOIN, NO ORDER: 17:12:10
total myisam: SELECT using INDEX and NON-KEY JOIN, NO ORDER: 38s
Queries per second: 2.63
Now going to do NON-KEY SELECT and JOINs
Just see the power of integer-keys and indexes!

Just 100 selects with like 'string' on a 1.7mln big table...
MySQL will go through all records now.
start myisam: SELECT with LIKE, NO ORDER: 17:12:10
Running 100 queries only...
SQL QUERY: select * from myisam_jstats_pages where page like '/categories/manufacturer/peter-eggink/dirDesc/results,221-240?error=404'
end myisam: SELECT with LIKE, NO ORDER: 17:14:12
total myisam: SELECT with LIKE, NO ORDER: 122s
Queries per second: 0.82
To make things worse we JOIN another table through non-indexed field..

start myisam: SELECT with LIKE and 1 NON-KEY JOIN, NO ORDER: 17:14:12
Running 25 queries only...
SQL QUERY: select myisam_jstats_pages.*, myisam_jstats_impressions.* from myisam_jstats_pages, myisam_jstats_impressions where myisam_jstats_pages.page_id=myisam_jstats_impressions.page_id and myisam_jstats_pages.page like '/component/virtuemart/thread,-reels-itrs/dirDesc/results,21-120?Itemid=0&filter_product='
end myisam: SELECT with LIKE and 1 NON-KEY JOIN, NO ORDER: 17:19:51
total myisam: SELECT with LIKE and 1 NON-KEY JOIN, NO ORDER: 339s
Queries per second: 0.07
Worst case - SELECT with LIKE, NON-KEY JOIN and ORDER BY STRING

start myisam: SELECT with LIKE and 1 NON-KEY JOIN, NO ORDER: 17:19:51
Running 25 queries only...
SQL QUERY: select myisam_jstats_pages.*, myisam_jstats_impressions.* from myisam_jstats_pages, myisam_jstats_impressions where myisam_jstats_pages.page_id=myisam_jstats_impressions.page_id and myisam_jstats_pages.page like '/categories/manufacturer/tora-magic/canes-candles/dirDesc/results,11-110?filter_product=' order by myisam_jstats_pages.page_title
end myisam: SELECT with LIKE and 1 NON-KEY JOIN, NO ORDER: 17:25:32
total myisam: SELECT with LIKE and 1 NON-KEY JOIN, NO ORDER: 341s
Queries per second: 0.07
end myisam tests: 17:25:32
total myisam tests: 873s
end global: 17:25:32
total global: 873s
#####################################

Best MySQL configuration file

[mysqld]
skip-name-resolve
myisam_use_mmap=1
max_allowed_packet=268435456

#table_open_cache=1024
#table_definition_cache=1024

innodb_buffer_pool_size=134217728
default-storage-engine=MyISAM

innodb_file_per_table=1

# THESE MADE DIFFERENCES
innodb_flush_log_at_trx_commit=2 
innodb_thread_concurrency=2 

# THESE MADE DIFFERENCE!
innodb_buffer_pool_size=128M 

# PART 2
innodb_sort_buffer_size=1M # 4m-slower

myisam_sort_buffer_size=1M
sort_buffer_size=1M

read_rnd_buffer_size=2M 
join_buffer_size=1M
read_buffer_size=2M 
# END PART 2

# KEEP ORIGINAL 8192 !
#table_open_cache=20000
#table_definition_cache=20000

# innodb_log_file_size=128M # original value 48M; value=16M - 21s # value=128M - 16s - can keep original
# thread_concurrency  - NOT NEEDED!
# innodb_log_buffer_size=16M # default 8M # value=2M - 15s # value=16M - 17s - can keep original
# thread_stack=2048K # value=256K - 31s # value=1M - 16s # value=2M - 16s - can keep original


# TO TEST WITH MYISAM
query_cache_limit=1M
#query_cache_min_res_unit=256

query_cache_type=1        
query_cache_size=256M     

key_buffer_size=64M 

#thread_cache=8 
#thread_cache_size=8 

tmp_table_size=128M
max_heap_table_size=128M

open_files_limit=20000

Leave a Reply

Your email address will not be published. Required fields are marked *