Performance (MySQL): verschil tussen versies

Uit De Vliegende Brigade
Naar navigatie springen Naar zoeken springen
Regel 70: Regel 70:
  
 
== Varchar ipv. txt ==
 
== Varchar ipv. txt ==
 +
 +
TXT-velden zijn veel langzamer dan VARCHAR-velden. Misschien omdat txt-velden extern worden opgeslagen (niet rechtstreeks in de tabel).
  
 
Deze sproc duurde 16s voor 1.000 regels - En da's veel te lang:
 
Deze sproc duurde 16s voor 1.000 regels - En da's veel te lang:

Versie van 11 nov 2019 11:46

MySQL langzamer dan je verwacht had?

  • Indexes - Ik heb dankzij indexes de tijdsduur van queries van minuten, kunnen reduceren tot secondes. Gewoon alle velden die in joins voorkomen, voorzien van een index → Indexes (MySQL)
  • Enkelvoudige joins: Vervang update-queries met meervoudige joins, door losse meerdere update-queries die elk met enkelvoudige joins werken
  • Soorten joins: Gewone joins zijn supersnel terwijl bv. left joins onthutsend langzaam zijn [1]
  • EXPLAIN: Gebruik EXPLAIN om te achterhalen waar performance een probleem is.

EXPLAIN

Bv. [2]:

EXPLAIN SELECT * FROM foo WHERE foo.bar = 'infrastructure as a service' OR foo.bar = 'iaas';

Samengestelde PK's: Let op de volgorde!

Zie Grouping (MySQL) voor een gruwelijk voorbeeld.

Casus: Update-query met dubbele join (aug. 2018)

Deze query eindigde steeds met een time-out na 300 seconde. Zo ver ik kan nagaan, stonden de indexes goed:

update description_tmp

join root_tmp 	on 	description_tmp.sku     =	root_tmp.sku_leading
join tool_tmp	on	root_tmp.tool_id	=	tool_tmp.tool_id

set en_part_02_application_special =
concat
(
   " for ",
   root_tmp.tool_brand, " ",
   tool_tmp.kind_en, " ",	# Hiervoor heb je de dubbbele join
   root_tmp.tool_type, " "
);

Echter, opgeslitst in twee enkelvoudige update-queries, doet-ie er maar zes seconde over:

# Use to update-queries with a single join each, in stead of one 
# update-query with a double join: Huge difference in execution time
#
# First update-query: root_tmp
##################################
#
alter table root_tmp add column kind_en varchar(45) null;

update root_tmp
join tool_tmp on root_tmp.tool_id = tool_tmp.tool_id
set root_tmp.kind_en = tool_tmp.kind_en;


# Second update-query
##################################
#
call add_column_unless_exists("description_tmp","en_part_02_application_special","varchar(100)");

update description_tmp
join root_tmp on description_tmp.sku = root_tmp.sku_leading
set en_part_02_application_special =
concat
(
   " for ",
   root_tmp.tool_brand, " ",
   root_tmp.kind_en, " ",
   root_tmp.tool_type
);    

Varchar ipv. txt

TXT-velden zijn veel langzamer dan VARCHAR-velden. Misschien omdat txt-velden extern worden opgeslagen (niet rechtstreeks in de tabel).

Deze sproc duurde 16s voor 1.000 regels - En da's veel te lang:

CREATE DEFINER=`root`@`localhost` PROCEDURE `sq_prepare_content_nl_combined_140`()
BEGIN

call add_column_unless_exists("content_tmp","part_80_meta_description_01","text");
update content_tmp set part_80_meta_description_01 = "Te koop op koolborstels.shop";

call add_column_unless_exists("content_tmp","part_80_meta_description_02","text");
update content_tmp set part_80_meta_description_02 = "Prijs:";

call add_column_unless_exists("content_tmp","part_80_meta_description_03","text");
update content_tmp set part_80_meta_description_03 = "Afmetingen:";

call add_column_unless_exists("content_tmp","part_80_sku","text");
update content_tmp set part_80_sku = "SKU:";

call add_column_unless_exists("content_tmp","part_80_for","text");
update content_tmp set part_80_for = "voor";

END

Vervolgens text vervangen door varchar(40) en performance 15s → 0,13s - 115x zo snel!

Zie ook

Bronnen