乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      MySQL優(yōu)化(五) MySQL 卓越資源...

       昵稱90415 2009-02-25

      MySQL優(yōu)化(五)

      2007-06-24 23:21 來(lái)源: imysql.cn 作者:葉金榮 網(wǎng)友評(píng)論 0 條 瀏覽次數(shù) 74

      7.3 鎖

      7.3.1 鎖機(jī)制

      當(dāng)前MySQL已經(jīng)支持 ISAM, MyISAM, MEMORY (HEAP) 類型表的表級(jí)鎖了,BDB 表支持頁(yè)級(jí)鎖,InnoDB 表支持行級(jí)鎖。
      很多時(shí)候,可以通過(guò)經(jīng)驗(yàn)來(lái)猜測(cè)什么樣的鎖對(duì)應(yīng)用程序更合適,不過(guò)通常很難說(shuō)一個(gè)鎖比別的更好,這全都要依據(jù)應(yīng)用程序來(lái)決定,不同的地方可能需要不同的鎖。
      想要決定是否需要采用一個(gè)支持行級(jí)鎖的存儲(chǔ)引擎,就要看看應(yīng)用程序都要做什么,其中的查詢、更新語(yǔ)句是怎么用的。例如,很多的web應(yīng)用程序大量的做查詢,很少刪除,主要是基于索引的更新,只往特定的表中插入記錄。采用基本的MySQL MyISAM 表就很合適了。
      MySQL中對(duì)表級(jí)鎖的存儲(chǔ)引擎來(lái)說(shuō)是釋放死鎖的。避免死鎖可以這樣做到:在任何查詢之前先請(qǐng)求鎖,并且按照請(qǐng)求的順序鎖表。
      MySQL中用于 WRITE(寫) 的表鎖的實(shí)現(xiàn)機(jī)制如下:

      • 如果表沒有加鎖,那么就加一個(gè)寫鎖。
      • 否則的話,將請(qǐng)求放到寫鎖隊(duì)列中。

      MySQL中用于 READ(讀) 的表鎖的實(shí)現(xiàn)機(jī)制如下:

      • 如果表沒有加寫鎖,那么就加一個(gè)讀鎖。
      • 否則的話,將請(qǐng)求放到讀鎖隊(duì)列中。

      當(dāng)鎖釋放后,寫鎖隊(duì)列中的線程可以用這個(gè)鎖資源,然后才輪到讀鎖隊(duì)列中的線程。
      這就是說(shuō),如果表里有很多更新操作的話,那么 SELECT 必須等到所有的更新都完成了之后才能開始。
      從 MySQL 3.23.33 開始,可以通過(guò)狀態(tài)變量 Table_locks_waitedTable_locks_immediate 來(lái)分析系統(tǒng)中的鎖表爭(zhēng)奪情況:

      mysql> SHOW STATUS LIKE 'Table%';
      +-----------------------+---------+
      | Variable_name         | Value   |
      +-----------------------+---------+
      | Table_locks_immediate | 1151552 |
      | Table_locks_waited    | 15324   |
      +-----------------------+---------+

      在 MySQL 3.23.7(在Windows上是3.23.25)以后,在 MyISAM 表中只要沒有沖突的 INSERT 操作,就可以無(wú)需使用鎖表自由地并行執(zhí)行 INSERTSELECT 語(yǔ)句。也就是說(shuō),可以在其它客戶端正在讀取 MyISAM 表記錄的同時(shí)時(shí)插入新記錄。如果數(shù)據(jù)文件的中間沒有空余的磁盤塊的話,就不會(huì)發(fā)生沖突了,因?yàn)檫@種情況下所有的新記錄都會(huì)寫在數(shù)據(jù)文件的末尾(當(dāng)在表的中間做刪除或者更新操作時(shí),就可能導(dǎo)致空洞)。當(dāng)空洞被新數(shù)據(jù)填充后,并行插入特性就會(huì)自動(dòng)重新被啟用了。
      如果想要在一個(gè)表上做大量的 INSERTSELECT 操作,但是并行的插入?yún)s不可能時(shí),可以將記錄插入到臨時(shí)表中,然后定期將臨時(shí)表中的數(shù)據(jù)更新到實(shí)際的表里。可以用以下命令實(shí)現(xiàn):

      mysql> LOCK TABLES real_table WRITE, insert_table WRITE;
      mysql> INSERT INTO real_table SELECT * FROM insert_table;
      mysql> TRUNCATE TABLE insert_table;
      mysql> UNLOCK TABLES;

      InnoDB 使用行級(jí)鎖,BDB 使用頁(yè)級(jí)鎖。對(duì)于 InnoDBBDB 存儲(chǔ)引擎來(lái)說(shuō),是可能產(chǎn)生死鎖的。這是因?yàn)?InnoDB 會(huì)自動(dòng)捕獲行鎖,BDB 會(huì)在執(zhí)行 SQL 語(yǔ)句時(shí)捕獲頁(yè)鎖的,而不是在事務(wù)的開始就這么做。
      行級(jí)鎖的優(yōu)點(diǎn)有:

      • 在很多線程請(qǐng)求不同記錄時(shí)減少?zèng)_突鎖。
      • 事務(wù)回滾時(shí)減少改變數(shù)據(jù)。
      • 使長(zhǎng)時(shí)間對(duì)單獨(dú)的一行記錄加鎖成為可能。

      行級(jí)鎖的缺點(diǎn)有:

      • 比頁(yè)級(jí)鎖和表級(jí)鎖消耗更多的內(nèi)存。
      • 當(dāng)在大量表中使用時(shí),比頁(yè)級(jí)鎖和表級(jí)鎖更慢,因?yàn)樗枰?qǐng)求更多的所資源。
      • 當(dāng)需要頻繁對(duì)大部分?jǐn)?shù)據(jù)做 GROUP BY 操作或者需要頻繁掃描整個(gè)表時(shí),就明顯的比其它鎖更糟糕。
      • 使用更高層的鎖的話,就能更方便的支持各種不同的類型應(yīng)用程序,因?yàn)檫@種鎖的開銷比行級(jí)鎖小多了。

      表級(jí)鎖在下列幾種情況下比頁(yè)級(jí)鎖和行級(jí)鎖更優(yōu)越:

      • 很多操作都是讀表。
      • 在嚴(yán)格條件的索引上讀取和更新,當(dāng)更新或者刪除可以用單獨(dú)的索引來(lái)讀取得到時(shí):
        UPDATE tbl_name SET column=value WHERE unique_key_col=key_value;
            DELETE FROM tbl_name WHERE unique_key_col=key_value;
      • SELECTINSERT 語(yǔ)句并發(fā)的執(zhí)行,但是只有很少的 UPDATEDELETE 語(yǔ)句。
      • 很多的掃描表和對(duì)全表的 GROUP BY 操作,但是沒有任何寫表。

      表級(jí)鎖和行級(jí)鎖或頁(yè)級(jí)鎖之間的不同之處還在于:
      將同時(shí)有一個(gè)寫和多個(gè)讀的地方做版本(例如在MySQL中的并發(fā)插入)。也就是說(shuō),數(shù)據(jù)庫(kù)/表支持根據(jù)開始訪問(wèn)數(shù)據(jù)時(shí)間點(diǎn)的不同支持各種不同的試圖。其它名有:時(shí)間行程,寫復(fù)制,或者是按需復(fù)制。
      原文: Versioning (such as we use in MySQL for concurrent inserts) where you can have one writer at the same time as many readers. This means that the database/table supports different views for the data depending on when you started to access it. Other names for this are time travel, copy on write, or copy on demand.
      按需復(fù)制在很多情況下比頁(yè)級(jí)鎖或行級(jí)鎖好多了。盡管如此,最壞情況時(shí)還是比其它正常鎖使用了更多的內(nèi)存。
      可以用應(yīng)用程序級(jí)鎖來(lái)代替行級(jí)鎖,例如MySQL中的 GET_LOCK()RELEASE_LOCK()。但它們是勸告鎖(原文:These are advisory locks),因此只能用于安全可信的應(yīng)用程序中。

      7.3.2 鎖表

      為了能有快速的鎖,MySQL除了 InnoDBBDB 這兩種存儲(chǔ)引擎外,所有的都是用表級(jí)鎖(而非頁(yè)、行、列級(jí)鎖)。
      對(duì)于 InnoDBBDB 表,MySQL只有在指定用 LOCK TABLES 鎖表時(shí)才使用表級(jí)鎖。在這兩種表中,建議最好不要使用 LOCK TABLES,因?yàn)?InnoDB 自動(dòng)采用行級(jí)鎖,BDB 用頁(yè)級(jí)鎖來(lái)保證事務(wù)的隔離。
      如果數(shù)據(jù)表很大,那么在大多數(shù)應(yīng)用中表級(jí)鎖會(huì)比行級(jí)鎖好多了,不過(guò)這有一些陷阱。
      表級(jí)鎖讓很多線程可以同時(shí)從數(shù)據(jù)表中讀取數(shù)據(jù),但是如果另一個(gè)線程想要寫數(shù)據(jù)的話,就必須要先取得排他訪問(wèn)。正在更新數(shù)據(jù)時(shí),必須要等到更新完成了,其他線程才能訪問(wèn)這個(gè)表。
      更新操作通常認(rèn)為比讀取更重要,因此它的優(yōu)先級(jí)更高。不過(guò)最好要先確認(rèn),數(shù)據(jù)表是否有很高的 SELECT 操作,而更新操作并非很‘急需’。
      表鎖鎖在一個(gè)線程在等待,因?yàn)榇疟P空間滿了,但是卻需要有空余的磁盤空間,這個(gè)線程才能繼續(xù)處理時(shí)就有問(wèn)題了。這種情況下,所有要訪問(wèn)這個(gè)出問(wèn)題的表的線程都會(huì)被置為等待狀態(tài),直到有剩余磁盤空間了。
      表鎖在以下設(shè)想情況中就不利了:

      • 一個(gè)客戶端提交了一個(gè)需要長(zhǎng)時(shí)間運(yùn)行的 SELECT 操作。
      • 其他客戶端對(duì)同一個(gè)表提交了 UPDATE 操作,這個(gè)客戶端就要等到 SELECT 完成了才能開始執(zhí)行。
      • 其他客戶端也對(duì)同一個(gè)表提交了 SELECT 請(qǐng)求。由于 UPDATE 的優(yōu)先級(jí)高于 SELECT,所以 SELECT 就會(huì)先等到 UPDATE 完成了之后才開始執(zhí)行,它也在等待第一個(gè) SELECT 操作。

      下列所述可以減少表鎖帶來(lái)的資源爭(zhēng)奪:

      • SELECT 速度盡量快,這可能需要?jiǎng)?chuàng)建一些摘要表。
      • 啟動(dòng) mysqld 時(shí)使用參數(shù) --low-priority-updates。這就會(huì)讓更新操作的優(yōu)先級(jí)低于 SELECT。這種情況下,在上面的假設(shè)中,第二個(gè) SELECT 就會(huì)在 INSERT 之前執(zhí)行了,而且也無(wú)需等待第一個(gè)SELECT 了。
      • 可以執(zhí)行 SET LOW_PRIORITY_UPDATES=1 命令,指定所有的更新操作都放到一個(gè)指定的鏈接中去完成。詳情請(qǐng)看“14.5.3.1 SET Syntax”。
      • LOW_PRIORITY 屬性來(lái)降低 INSERT,UPDATEDELETE 的優(yōu)先級(jí)。
      • HIGH_PRIORITY 來(lái)提高 SELECT 語(yǔ)句的優(yōu)先級(jí)。詳情請(qǐng)看“14.1.7 SELECT Syntax”。
      • 從MySQL 3.23.7 開始,可以在啟動(dòng) mysqld 時(shí)指定系統(tǒng)變量 max_write_lock_count 為一個(gè)比較低的值,它能強(qiáng)制臨時(shí)地提高表的插入數(shù)達(dá)到一個(gè)特定值后的所有 SELECT 操作的優(yōu)先級(jí)。它允許在 WRITE 鎖達(dá)到一定數(shù)量后有 READ 鎖。
      • 當(dāng) INSERT SELECT 一起使用出現(xiàn)問(wèn)題時(shí),可以轉(zhuǎn)而采用 MyISAM 表,它支持并發(fā)的SELECT INSERT 操作。
      • 當(dāng)在同一個(gè)表上同時(shí)有插入和刪除操作時(shí),INSERT DELAYED 可能會(huì)很有用。詳情請(qǐng)看“14.1.4.2 INSERT DELAYED Syntax”。
      • 當(dāng) SELECT DELETE 一起使用出現(xiàn)問(wèn)題時(shí),DELETELIMIT 參數(shù)可能會(huì)很有用。詳情請(qǐng)看“14.1.1 DELETE Syntax”
      • 執(zhí)行 SELECT 時(shí)使用 SQL_BUFFER_RESULT 有助于減短鎖表的持續(xù)時(shí)間.詳情請(qǐng)看“14.1.7 SELECT Syntax”。
      • 可以修改源代碼 `mysys/thr_lock.c',只用一個(gè)所隊(duì)列。這種情況下,寫鎖和讀鎖的優(yōu)先級(jí)就一樣了,這對(duì)一些應(yīng)用可能有幫助。

      以下是MySQL鎖的一些建議:

      • 只要對(duì)同一個(gè)表沒有大量的更新和查詢操作混在一起,目前的用戶并不是問(wèn)題。
      • 執(zhí)行 LOCK TABLES 來(lái)提高速度(很多更新操作放在一個(gè)鎖之中比沒有鎖的很多更新快多了)。將數(shù)據(jù)拆分開到多個(gè)表中可能也有幫助。
      • 當(dāng)MySQL碰到由于鎖表引起的速度問(wèn)題時(shí),將表類型轉(zhuǎn)換成 InnoDBBDB 可能有助于提高性能。詳情請(qǐng)看“16 The InnoDB Storage Engine”和“15.4 The BDB (BerkeleyDB) Storage Engine”。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多