Mysql基礎調優

mysql基礎的優化方式

一、利用索引加快查詢速度
二、利用查詢緩存或者旁掛式緩存,提升訪問速度
    緩存:k/v
        key:查詢語句的hash值
        value:查詢語句的執行結果
    哪些查詢可能不會被緩存?
        查詢語句中包含UDF(User-Defined Functions)
        存儲函數
        用戶自定義變量
        臨時表
        mysql系統表或者是包含列級別權限的查詢
        有着不肯定結果值的函數(now());
    查詢緩存相關的服務器變量:
        query_cache_limit:可以緩存的最大查詢結果,(單語句結果集大小上限)
            有着較大結果集的語句,顯式使用SQL_NO_CACHE,以免先緩存再移出,也就是查詢的時候用select * from students SQL_NO_CACHE
        query_cache_min_res_unit:內存塊的最小分配單位,緩存太小的查詢結果集會浪費內存空間
            較小的值會減小空間浪費,但會致使更頻繁地內存分配及回收操做,較大值的會帶來空間浪費
        query_cache_size:查詢緩存空間的總共可用的大小,單位是字節,必須是1024的整數倍
        query_cache_strip_comments
        query_cache_type:緩存功能啓用與否;
            ON:啓用;
            OFF:禁用;
        DEMAND:按需緩存,僅緩存SELECT語句中帶SQL_CACHE的查詢結果;
        query_cache_wlock_invalidate:若是某表被其它鏈接鎖定,是否仍然能夠從查詢緩存中返回查詢結果,默認爲OFF表示能夠,ON則表示不能夠;
    狀態變量:
        mysql> SHOW GLOBAL STATUS LIKE 'Qcache%';
                    +-------------------------+----------+
                    | Variable_name           | Value    |
                    +-------------------------+----------+
                    | Qcache_free_blocks      | 1        |
                    | Qcache_free_memory      | 16759688 |
                    | Qcache_hits             | 0        |   ##查詢緩存的命中率
                    | Qcache_inserts          | 0        |
                    | Qcache_lowmem_prunes    | 0        |
                    | Qcache_not_cached       | 0        |
                    | Qcache_queries_in_cache | 0        |
                    | Qcache_total_blocks     | 1        |
                    +-------------------------+----------+      
         mysql> show global status like '%Com_select%';
        +---------------+-------+
        | Variable_name | Value |
        +---------------+-------+
        | Com_select    | 12    |    ##表示查詢的次數
        +---------------+-------+
    命中率:
        Qcache_hits/Com_select 
三、InnoDB存儲引擎相關的參數:
    innodb_buffer_pool_size:
        索引、數據、插入數據時的緩衝區,數據先保存在內存緩衝區,從內存緩衝區保存到磁盤,作爲專用服務器時設置爲內存的70-80%;
        若是數據集自己較小,可根據數據變化幅度及規劃的時長設定合理值,比預估的目標值略大;
    innodb_buffer_pool_instances:
        buffer_pool的區段(實例)數量,內存緩衝區被分紅多個區端,這樣鎖定的時候不會鎖定整張表,可能只是鎖定表的一部分
四、事務日誌:
    innodb_log_files_in_group:一組內事物日誌文件數量,至少2個;
    innodb_log_file_size:日誌文件大小,默認爲5M,建議調大此值;
    innodb_flush_logs_at_trx_commit:
        0:log buffer(內存)每秒一次同步到log file中,且同時會進行log file到data file的同步操做;也就是每秒鐘一次將內存緩衝區中的數據同步到事物日誌中,同時同步到數據文件中。
        1:每次提交時,log buffer同步到log file,同時進行log file到data file的同步操做;
        2:每次提交時,log buffer同步到log file,但不會同時進行log file到data file的同步操做;
        建議:關閉autocommit,然後將此值設置爲1或2;
    innodb_file_per_table:innodb的諸多高級特性都依賴於此參數;
    innodb_read_io_threads:
    innodb_write_io_threads
        文件讀寫的io線程數,可根據併發量和CPU核心數適當調整;
    innodb_open_files:innodb可打開的文件數量上限;
    innodb_thread_concurrency=內核級能夠使用的線程數,通常爲cpu的2倍
    skip_name_resolve:
    max_connections:
五、表分區:
    表分區能夠提升查詢和寫操做的效率,對錶進行分區後表結構文件仍是一個,但表空間文件會變成多個,查詢或更改數據時只須要在表的分區內進行就能夠,而沒必要查詢整張表,大大提升效率,使每一個分區單獨管理、單獨使用
    根據範圍劃分:
        MariaDB [mydb]> CREATE TABLE students (id INT, name VARCHAR(100), age TINYINT UNSIGNED NOT NULL, gender ENUM('F','M')) PARTITION BY range(age)(partition youngman values less than (40), partition middleman values less than (70), partition oldman values less than maxvalue);
        [root@node2 ~]#for i in {1..1000};do mysql -e "insert into mydb.students values($i,'stu$i',$[$[RANDOM%90]+18],'${gender[$[RANDOM%2]]}')";done
        [root@node2 mydb]#ls   ##能夠看到表結構文件只有一個,但表空間文件被分紅了三個
        db.opt  students.frm  students.par  students#P#middleman.ibd  students#P#oldman.ibd  students#P#youngman.ibd
    根據hash劃分:
        MariaDB [mydb]> CREATE TABLE students (id INT, name CHAR(100) NOT NULL, age TINYINT UNSIGNED, gender ENUM('F','M')) PARTITION BY hash(id) PARTITIONS 5;   
        [root@node2 mydb]#for i in {1..1000};do mysql -e "insert into mydb.students values($i,'stu$i',$[$[RANDOM%90]+18],'${gender[$[RANDOM%2]]}')";done
        [root@node2 mydb]#ls
        db.opt  students.frm  students.par  students#P#p0.ibd  students#P#p1.ibd  students#P#p2.ibd  students#P#p3.ibd  students#P#p4.ibd
        指明分區的數量; 注意這裏不能對名字進行哈希,由於名字的數據類型是char或者是varchar,會補空格,因此不是肯定的,就沒法進行哈希,哈希的值不是肯定的
    根據列表劃分:
        MariaDB [mydb]> CREATE TABLE students (id INT, name CHAR(100) NOT NULL, age TINYINT UNSIGNED, gender ENUM('F','M'), majorid TINYINT UNSIGNED NOT NULL) PARTITION BY list(majorid) (PARTITION p0 VALUES IN (1,4,7), PARTITION p1 VALUES IN (2,5,8), PARTITION p2 VALUES IN (3,6,9));
        [root@node2 mydb]#for i in {1..1000};do mysql -e "insert into mydb.students values($i,'stu$i',$[$[RANDOM%90]+18],'${gender[$[RANDOM%2]]}',$[$[RANDOM%9]+1])";done
        [root@node2 mydb]#ls
        db.opt  students.frm  students.par  students#P#p0.ibd  students#P#p1.ibd  students#P#p2.ibd
六、sql mode:
    定義mysqld對約束等違反時的響應行爲等設定;
        經常使用的mode:
            traditional
            strict_trans_tables
            strict_all_tables
        修改方式:
            mysql> set global sql_mode='mode';
            mysql> set @@global.sql_mode='mode';
總結:
    1,利用索引加快查詢速度
    2,利用查詢緩存或旁掛式緩存提供訪問速度,利用變量來提升命中率。
    3,表分區能夠提升查詢和寫操做的效率
相關文章
相關標籤/搜索