มีเกณฑ์เปรียบเทียบสมรรถนะ MySQL เพื่อวัดผลกระทบของ utf8_unicode_ci เทียบกับ utf8_general_ci หรือไม่?


13

ผมอ่านที่นี่และมีว่าการใช้utf8_unicode_ciการเปรียบเทียบเพื่อให้แน่ใจว่าการรักษาที่ดีขึ้นของข้อความ Unicode (ตัวอย่างเช่นมัน knowns วิธีการขยายตัวอักษรเช่น 'œ' เป็น 'OE' สำหรับการค้นหาและการสั่งซื้อ) เมื่อเทียบกับการเริ่มต้นutf8_general_ciซึ่งโดยทั่วไปเพียงแถบกำกับ แต่น่าเสียดายที่ทั้งสองแหล่งข่าวระบุว่าจะช้ากว่าเล็กน้อยutf8_unicode_ciutf8_general_ci

ดังนั้นคำถามของฉันคืออะไร "ช้าลงเล็กน้อย" หมายความว่าอย่างไร มีใครบ้างที่ใช้มาตรฐาน? เรากำลังพูดถึงผลกระทบของประสิทธิภาพการทำงาน -0.01% หรือมากกว่า -25%

ขอบคุณสำหรับความช่วยเหลือของคุณ.


เท่าที่เป็นมาตรฐานทำไมไม่ใช้เวลาแบบสอบถาม? ฉันอาจจะเป็นคนงี่เง่า แต่ถ้าคุณใช้ VM และทดสอบเวลาของแบบสอบถามบนเคียวรีที่ซับซ้อนขนาดใหญ่สำหรับการเข้ารหัสอักขระทั้งสอง (ฉันไม่เคยเห็นการเปรียบเทียบทำมาก่อนหน้านี้)
Ablue

คำตอบ:


8

ฉันไม่พบการวัดประสิทธิภาพใด ๆ ในอินเทอร์เน็ตดังนั้นฉันตัดสินใจที่จะทำการวัดประสิทธิภาพด้วยตัวเอง

ฉันสร้างตารางง่าย ๆ ที่มีแถว 500,000 แถว:

CREATE TABLE test(
  ID INT(11) DEFAULT NULL,
  Description VARCHAR(20) DEFAULT NULL
)
ENGINE = INNODB
CHARACTER SET utf8
COLLATE utf8_general_ci;

จากนั้นฉันก็เติมข้อมูลด้วยการสุ่มโดยรันโพรซีเดอร์ที่เก็บไว้นี้:

CREATE PROCEDURE randomizer()
BEGIN
  DECLARE i INT DEFAULT 0;
  DECLARE random CHAR(20) ;

  theloop: loop
    SET random = CONV(FLOOR(RAND() * 99999999999999), 20, 36);

    INSERT INTO test VALUES (i+1, random);

    SET i=i+1;

    IF i = 500000 THEN
      LEAVE theloop;
    END IF;

  END LOOP theloop;
END

จากนั้นฉันสร้างโพรซีเดอร์ที่เก็บไว้ต่อไปนี้เพื่อสร้างเกณฑ์มาตรฐาน SELECT, SELECT พร้อม LIKE และทำการเรียงลำดับ (SELECT พร้อม ORDER BY):

CREATE benchmark_simple_select()
BEGIN
  DECLARE i INT DEFAULT 0;

  theloop: loop

    SELECT * FROM test WHERE Description = 'test' COLLATE utf8_general_ci;

    SET i = i + 1;

    IF i = 30 THEN
      LEAVE theloop;
      END IF;

  END LOOP theloop;

END

CREATE PROCEDURE benchmark_select_like()
BEGIN
  DECLARE i INT DEFAULT 0;

  theloop: loop

    SELECT * FROM test WHERE Description LIKE '%test' COLLATE utf8_general_ci;

    SET i = i + 1;

    IF i = 30 THEN
      LEAVE theloop;
      END IF;

  END LOOP theloop;

END

CREATE PROCEDURE benchmark_order_by()
BEGIN
  DECLARE i INT DEFAULT 0;

  theloop: loop

    SELECT * FROM test WHERE ID > FLOOR(1 + RAND() * (400000 - 1)) ORDER BY Description COLLATE utf8_general_ci LIMIT 1000;

    SET i = i + 1;

    IF i = 10 THEN
      LEAVE theloop;
      END IF;

  END LOOP theloop;

END

ในกระบวนงานที่เก็บไว้ข้างต้นใช้การเปรียบเทียบ utf8_general_ci แต่แน่นอนในระหว่างการทดสอบฉันใช้ทั้ง utf8_general_ci และ utf8_unicode_ci

ฉันเรียกแต่ละโพรซีเดอร์ที่เก็บไว้ 5 ครั้งสำหรับการเปรียบเทียบแต่ละครั้ง (5 ครั้งสำหรับ utf8_general_ci และ 5 ครั้งสำหรับ utf8_unicode_ci) จากนั้นคำนวณค่าเฉลี่ย

นี่คือผลลัพธ์:

benchmark_simple_select () พร้อม utf8_general_ci: 9957 ms
benchmark_simple_select () with utf8_unicode_ci: 10271 ms
ในการทดสอบประสิทธิภาพโดยใช้ utf8_unicode_ci นั้นช้ากว่า utf8_general_ci 3.2%

benchmark_select_like () with utf8_general_ci: 11441 ms
benchmark_select_like () with utf8_unicode_ci: 12811 ms
ในเบนช์มาร์กนี้ใช้ utf8_unicode_ci ช้ากว่า utf8_general_ci 12%

benchmark_order_by () กับ utf8_general_ci: 11944 ms
benchmark_order_by () กับ utf8_unicode_ci: 12887 ms
ในเบนช์มาร์กนี้การใช้ utf8_unicode_ci นั้นช้ากว่า utf8_general_ci 7.9%


2

ฉันไม่เห็นมาตรฐานใด ๆ แต่คุณสามารถรันด้วยตัวเองโดยใช้ฟังก์ชันBENCHMARK :

BENCHMARK (นับ expr)

ตามที่ Matthew แนะนำคุณอาจเรียกใช้การติดตั้ง MYSQL แบบขนาน แต่พิจารณาว่าอาจมีความแตกต่างอย่างมากระหว่างสถาปัตยกรรมที่แตกต่างกัน (sparc, intel, 32 บิต, 64 บิต, ... )

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.