mysql is very slow on LEFT JOIN - mysql

I'm converting my entire site from MYSQLi to PDO.
Now I have one problem with one of my larger query's
SELECT
kl.klant_id AS klant_id,
kl.klant_naam AS klant_naam,
kl.klant_adres AS klant_adres,
kl.klant_postcode AS klant_postcode,
kl.klant_plaats AS klant_plaats,
kl.klant_land AS klant_land,
kl.klant_telefoon AS klant_telefoon,
kl.klant_fax AS klant_fax,
kl.klant_email AS klant_email,
kl.klant_contactpersoon AS klant_contactpersoon,
gr.groep_id AS groep_id,
gr.groep_naam AS groep_naam,
IF(ft.factuur_isgroep>0,gr.groep_factuur_adress,ft.factuur_adres) AS factuur_adres,
IF(ft.factuur_isgroep>0,gr.groep_factuur_postbus,ft.factuur_postbus) AS factuur_postbus,
IF(ft.factuur_isgroep>0,gr.groep_factuur_postcode,ft.factuur_postcode) AS factuur_postcode,
IF(ft.factuur_isgroep>0,gr.groep_factuur_plaats,ft.factuur_plaats) AS factuur_plaats,
IF(ft.factuur_isgroep>0,gr.groep_factuur_land,ft.factuur_land) AS factuur_land,
IF(ft.factuur_isgroep>0,gr.groep_factuur_iban,ft.factuur_iban) AS factuur_iban,
IF(ft.factuur_isgroep>0,gr.groep_factuur_bic,ft.factuur_bic) AS factuur_bic,
IF(ft.factuur_isgroep>0,gr.groep_factuur_telefoon,ft.factuur_telefoon) AS factuur_telefoon,
IF(ft.factuur_isgroep>0,gr.groep_factuur_contactpersoon,ft.factuur_contactpersoon) AS factuur_contactpersoon,
IF(ft.factuur_isgroep>0,gr.groep_factuur_bymail,ft.factuur_bymail) AS factuur_bymail,
IF(ft.factuur_isgroep>0,gr.groep_factuur_email,ft.factuur_email) AS factuur_email,
IF(ft.factuur_isgroep>0,gr.groep_extra,ft.factuur_opmerkingen) AS factuur_opmerkingen,
al.alarm_ccs_type AS alarm_ccs,
al.alarm_gprs AS alarm_gprs,
al.alarm_gprs_provider AS alarm_gprs_provider,
al.alarm_gprs_sn AS alarm_gprs_sn,
al.alarm_doormelding AS alarm_doormelding,
al.alarm_onderhoud AS alarm_onderhoud,
al.alarm_onderhoud_laatst AS alarm_onderhoud_laatst,
al.alarm_certificaat AS alarm_certificaat,
al.alarm_cer_state AS alarm_cer_state,
al.alarm_cer_uitgifte AS alarm_cer_uitgifte,
al.alarm_risicoklasse AS alarm_risicoklasse,
mk.pac_naam AS meldkamer_naam,
mk.pac_clientnr AS meldkamer_clientnr,
mk.pac_promnr AS meldkamer_promnr,
mk.pac_backup_clientnr AS meldkamer_backup_clientnr,
mk.pac_backup_promnr AS meldkamer_backup_promnr
FROM klanten AS kl
LEFT JOIN groepen AS gr ON kl.klant_groupid > 0 AND kl.klant_groupid = gr.groep_id
LEFT JOIN alarm AS al ON al.alarm_klantid = kl.klant_id
LEFT JOIN meldkamer AS mk ON mk.pac_klantid = kl.klant_id
LEFT JOIN factuur AS ft ON ft.factuur_klantid = kl.klant_id
ORDER BY klant_id ASC
The query works but on PDO it's very slow. (+/- 3sec while mysqli is less then 1sec)
Is this a known problem of PDO or is there something wrong with my query?
I've read a lot of other poeple with simular problems but they all have more complex query's than this.
Solved Thanks to cale_b. My problem was indexing my columns. I indexed all the columns on i used in the above query and now it's very fast. Thanks.

Related

Optimization of a large database query

I would like to ask if there is any way to optimize the following query:
SELECT SQL_BIG_RESULT DISTINCT u.spy_tech,
u.computer_tech,
u.military_tech,
u.defence_tech,
u.shield_tech,
u.energy_tech,
u.hyperspace_tech,
u.combustion_tech,
u.impulse_motor_tech,
u.hyperspace_motor_tech,
u.laser_tech,
u.ionic_tech,
u.buster_tech,
u.intergalactic_tech,
u.expedition_tech,
u.metal_proc_tech,
u.crystal_proc_tech,
u.deuterium_proc_tech,
u.technologia_bankowa,
u.technologia_kolonizacyjna,
u.technologia_optymalizacji,
u.technologia_otchlani,
u.graviton_tech,
SUM(p.small_ship_cargo) as small_ship_cargo,
SUM(p.big_ship_cargo) as big_ship_cargo,
SUM(p.light_hunter) as light_hunter,
SUM(p.heavy_hunter) as heavy_hunter,
SUM(p.crusher) as crusher,
SUM(p.battle_ship) as battle_ship,
SUM(p.colonizer) as colonizer,
SUM(p.recycler) as recycler,
SUM(p.spy_sonde) as spy_sonde,
SUM(p.bomber_ship) as bomber_ship,
SUM(p.solar_satelit) as solar_satelit,
SUM(p.destructor) as destructor,
SUM(p.dearth_star) as dearth_star,
SUM(p.battleship) as battleship,
SUM(p.lune_noir) as lune_noir,
SUM(p.ev_transporter) as ev_transporter,
SUM(p.star_crasher) as star_crasher,
SUM(p.giga_recykler) as giga_recykler,
SUM(p.dm_ship) as dm_ship,
SUM(p.apocalypse) as apocalypse,
SUM(p.annihilator) as annihilator,
SUM(p.devastator) as devastator,
SUM(p.fleet_save) as fleet_save,
u.r_badawczy,
u.r_budowlany,
u.r_militarny,
u.r_obrony,
u.r_paliwowy,
u.r_gospodarczy,
u.r_planetarny,
u.r_magazynowy,
u.r_energetyczny,
u.r_ekonomiczny,
u.r_odkrywczy,
u.r_max,
u.r_speed,
u.r_moon,
u.r_dm,
u.r_terra,
SUM(p.misil_launcher) as misil_launcher,
SUM(p.small_laser) as small_laser,
SUM(p.big_laser) as big_laser,
SUM(p.gauss_canyon) as gauss_canyon,
SUM(p.ionic_canyon) as ionic_canyon,
SUM(p.buster_canyon) as buster_canyon,
SUM(p.small_protection_shield) as small_protection_shield,
SUM(p.big_protection_shield) as big_protection_shield,
SUM(p.planet_protector) as planet_protector,
SUM(p.graviton_canyon) as graviton_canyon,
SUM(p.orbital_station) as orbital_station,
SUM(p.dzialo_pulsacyjne) as dzialo_pulsacyjne,
SUM(p.dzialo_fotonowe) as dzialo_fotonowe,
SUM(p.interceptor_misil) as interceptor_misil,
SUM(p.interplanetary_misil) as interplanetary_misil,
u.id,
u.ally_id,
u.onlinetime,
s.tech_rank AS old_tech_rank,
s.build_rank AS old_build_rank,
s.defs_rank AS old_defs_rank,
s.fleet_rank AS old_fleet_rank,
s.total_rank AS old_total_rank,
s.total_points_old AS total_points_old,
s.fleet_points_old AS fleet_points_old,
s.defs_points_old AS defs_points_old,
s.build_points_old AS build_points_old,
s.tech_points_old AS tech_points_old
FROM test_users as u
LEFT JOIN test_statpoints as s ON s.stat_type = 1 AND s.id_owner = u.id
LEFT JOIN test_planets as p ON u.id = p.id_owner
WHERE u.user_lastip != "127.0.0.1"
AND u.bana = "0"
AND u.authlevel = "0"
AND u.universe = "1"
GROUP BY s.id_owner, u.id
On my VPS, the query takes 8 seconds and the result is about 10,000 results. Although I improved the machine twice, to 8x2,4CPU, 16gb RAM, the query time has not changed.
So I thought to optimize the above-mentioned query or work on VPS configuration and find a bottleneck that can generate such time.
Table STATPOINTS:
Table USERS:
I do not know if I have given you an insight into the tables, when it comes to something else I would ask for guidance.
Explain:
Your query can run faster if you add the following indexes:
create index ix1 on user (bana, authlevel, universe);
create index ix2 on test_statpoints (stat_type, id_owner);
create index ix3 on test_planets (id_owner);
They include the access columns according to the join predicates.

Select * from view more than 10x slower than executing the views create statement directly with MySQL 5.7

I have created a view as a join of several tables to hide the complexity.
Now when I execute a select * from view it takes more than 10x of the execution time it takes to execute the select statement directly, that defines the view (about 70 ms vs 900 ms).
This behaviour occurs on a MySQL 5.7.23 server.
I compared the execution plans for both queries and the only difference (as expected) is the derived table:
Is this a normal behaviour of views or how can I fix it?
P.S.:
The create view statement as requested (names where obfuscated):
create view vrs as select
rs."id" as "id",
l."language" as "language",
rss."t" as "discriminator",
rss."type" as "type",
coalesce(lt3."text", concat('!',s3."textkey",'(',l."language",')')) as "typeText",
rss."model" as "model",
coalesce(lt2."text", concat('!',s2."textkey",'(',l."language",')')) as "modelText",
rs."name" as "name",
rs."reqCATGroup" as "CATGroup",
rs."devID" as "devID",
case s."builtIn"
when 0 then s."displayName"
else (select lt1."text"
from loctext lt1
where lt1."language"=l."language"
and lt1."textkey"=s."displayName")
end as "sName",
s."id" as "sId",
s."postcode" as "sPostcode",
s."place" as "sPlace",
s."street" as "sStreet",
s."streetNumber" as "sStreetNumber",
s."tId" as "tId",
t."tName" as "tName",
rss."CCVMajor" as "CCVMajor",
rss."CCVMinor" as "CCVMinor",
rss."CCVPatch" as "CCVPatch",
rss."CCHV" as "CCHV",
coalesce(lHw."text", concat('!',sHw."textkey",'(',l."language",')')) as "CCHVText",
rss."MCVMajor" as "MCVMajor",
rss."MCVMinor" as "MCVMinor",
rss."MCVPatch" as "MCVPatch",
rss."level",
coalesce(lLevel."text", concat('!', sLevel."textkey", '(', l."language", ')')) as "levelText",
rss."event",
coalesce(lEvent."text", concat('!', sEvent."textkey", '(', l."language", ')')) as "eventText",
rss."isBusy" as "isBusy",
rss."tsLastComIn" as "tsLastCom",
rss."tsBT" AS "tsBT",
b1."ordinal" as "isSending",
coalesce(ltSend."text", concat('!',b1."textkey",'(',l."language",')')) as "isSendingText",
b2."ordinal" as "isReceiving",
coalesce(ltReceive."text", concat('!',b2."textkey",'(',l."language",')')) as "isReceivingText",
rs."historyCreateDevTs",
rs."historyCreateDevUserId",
rs."historyCreateDevUserLoginName",
rs."historyModifyDevLinkTs",
rs."historyModifyDevLinkUserId",
rs."historyModifyDevLinkUserLoginName",
rs."monitorStartTs",
rs."monitorEndTs"
from synch rss
cross join loclanguages l
join cfgrs rs on rs."id" = rss."id"
join cfgs s on s."id" = rs."sId"
join cfgt t on t."id" = s."tId"
left join locmodel s2 on s2."ordinal" = rss."model"
left join loctext lt2 on lt2."textkey" = s2."textkey" and lt2."language" = l."language"
left join loctype s3 on s3."ordinal" = rss."type"
left join loctext lt3 on lt3."textkey" = s3."textkey" and lt3."language" = l."language"
left join locbooleanrange b1 on rs."sending"+1 = b1."ordinal"
left join loctext ltSend on ltSend."textkey" = b1."textkey" and ltSend."language" = l."language"
left join locbooleanrange b2 on rs."receiving"+1 = b2."ordinal"
left join loctext ltReceive on ltReceive."textkey" = b2."textkey" and ltReceive."language" = l."language"
left join loceventlevel sLevel on sLevel."ordinal" = rss."level"
left join loctext lLevel on lLevel."textkey" = sLevel."textkey" and lLevel."language" = l."language"
left join locevent sEvent on sEvent."ordinal" = rss."event" and sEvent."type" = rss."type"
left join loctext lEvent on lEvent."textkey" = sEvent."textkey" and lEvent."language" = l."language"
left join loccchv sHw on sHw."ordinal" = rss."CCHV"
left join loctext lHw on lHw."textkey" = sHw."textkey" and lHw."language" = l."language"
where rs."deleted" = 0
;
P.P.S.: The complete execution plans look like this:
direct call:
view:
This link is for MySQL 8.0, but when I last had performance issues with Views in MySQL 5.6, 5.7, and went digging, I got the same answer: You basically cannot take advantage of Indexes when using Views.
https://dev.mysql.com/doc/refman/8.0/en/view-restrictions.html
I personally found Views in MySQL to Not be useful overall, due to limitations like the ones described above, particularly due to the performance hit.
Readers - if somehow Views in MySQL can perform, I certainly missed a key memo somewhere. Please correct me if this is the case.

MS Access: Join on three tables with condition

In an MS Access database I try to make a join on three tables with conditions.
My current approach does not work:
SELECT
P.[COL1],
P.[COL2],
P.[COL3],
P.[COL4],
P.[COL5],
P.[PRGUID],
P.[COL6],
P.[COL7],
ARTIKEL.[COL1],
ARTIKEL.[NUMBER],
P.[PST_NR],
RECHNUNGEN.[RG_STORNO]
FROM P, A, R
WHERE R.[TIMEST] > #{from:yyyy-MM-dd HH:mm:ss}#
AND R.[TIMEST] < #{until:yyyy-MM-dd HH:mm:ss}#
AND A.[NUMBER] = VAL(P.[PLUX])
AND R.[RGUID] = P.[PRGUID] "
;
because the datasets in table P that do not have a corresponding entry in table A (condition: A.[NUMMER] = VAL(P.[PLUX])) are not returned.
I tried an approach with JOIN but I cannot find the right syntax.
Thank you #Gustav
The GUI designer helped (didn't even know it is there - just used SQL so far).
SELECT P.ColumnX, A.ColumnY, R.ColumnZ
FROM (P LEFT OUTER JOIN A.[NUMBER]) = VAL(P.[PLUX]))
INNER JOIN R ON P.[PRGUID] = R.[RGUID]
WHERE R.[TIMEST] > #yyyy-MM-dd HH:mm:ss#
AND R.[TIMEST] < #yyyy-MM-dd HH:mm:ss#

How can optimize the query with join

I have a query large query which is taking more time to execute.How can i reduce the execution time of the query using Join.Here is myt query.
SELECT mdi.Member_Id,
dp.Payment1_Date AS Duchess_Payment1_Date,
dp.Payment1_Method AS Duchess_Payment1_Method,
dp.Payment1_By AS Duchess_Payment1_By,
dp.Payment1_Amount AS Duchess_Payment1_Amount,
dp.Payment2_Date AS Duchess_Payment2_Date,
dp.Payment2_Method AS Duchess_Payment2_Method,
dp.Payment2_By AS Duchess_Payment2_By,
dp.Payment2_Amount AS Duchess_Payment2_Amount,
mha.First_Name AS Member_First_Name,
mha.Middle_Name AS Member_Middle_Name,
mha.Last_Name AS Member_Last_Name,
mha.Address AS Member_Address,
mha.City AS Member_City,
mha.State AS Member_State,
mha.Zip AS Member_Zip,
mha.Nickname AS Member_Nickname,
mha.Phone AS Member_Phone,
mha.Mobile AS Member_Mobile,
mha.Email AS Member_Email,
mwa.First_Name AS Work_First_Name,
mwa.Middle_Name AS Work_Middle_Name,
mwa.Last_Name AS Work_Last_Name,
mwa.Address AS Work_Adrress,
mwa.City AS Work_City,
mwa.State AS Work_State,
mwa.Zip AS Work_Zip,
mwa.Phone AS Work_Phone,
(CASE WHEN mha.Preferred=0 THEN 'Work Address' WHEN mha.Preferred=1 THEN 'Home Address' END)AS Preferred,
mmt.Admiral_Title,
mmt.Spouse_Title,
mmt.Couple_Title,
mdi.Year AS Duchess_Year,
mdi.College AS Duchess_College,
mdi.Major AS Duchess_Major,
mdi.Sorority AS Duchess_Sorority,
mdi.Parent_Name AS Duchess_Parent_Name,
mdi.Escort_Name AS Duchess_Escort_Name
FROM duchess_payment dp
JOIN member_duchess_info mdi ON mdi.Duchess_Id = dp.Duchess_Id
JOIN member_home_address mha ON mha.Member_Id = mdi.Member_Id
JOIN member_work_address mwa ON mwa.Member_Id = mdi.Member_Id
JOIN member_mailing_title mmt ON mmt.Member_Id = mdi.Member_Id
ORDER BY dp.Duchess_Id;
this is the way Iam using . Is it corrct?.
when i try to executing that query it is still taking more time.
here is the explain of the query
Use indexes on the items on which you are performing joins e.g Duchess_Id, Member_Id etc

Mysql 4 to 5 query conversion - join headaches

If anyone can help me rewrite my query to work in mysql 5 I would be very grateful. If anyone can provide links to solid, simple tutorials on how to rewrite old queries that would also be great.
My current (version 4) query looks like this:
SELECT
course.course_code,
course.course_title_sv AS course_title,
course.course_u_credits,
course.course_successive_level_scb_id,
s.successive_level_scb_order,
s.successive_level_scb_code,
LEFT (education_level.edu_level_name_sv, 1) AS course_edu_level, course.course_level,
GROUP_CONCAT(DISTINCT h.head_area_hv_title_sv SEPARATOR ', ') AS head_area_hv
FROM
course, course_event, course_event_package_links, package, education_level
LEFT JOIN
course_has_head_area_hv ON(course.course_id = course_has_head_area_hv.course_id)
LEFT JOIN
head_area_hv h ON(h.head_area_hv_id = course_has_head_area_hv.head_area_hv_id)
LEFT JOIN
successive_level_scb s ON(s.successive_level_scb_id = course.course_successive_level_scb_id)
WHERE
course.course_edu_level=education_level.edu_level_id AND
course.course_id=course_event.course_id AND
course_event.course_event_id=course_event_package_links.course_event_id AND
course_event_package_links.package_id=package.package_id AND
course.course_successive_level_scb_id != '' AND
package.package_id='6318'
GROUP BY course.course_id
Simply replace
SELECT ...
FROM course, course_event, course_event_package_links
...
WHERE course.course_id=course_event.course_id
AND course_event.course_event_id=course_event_package_links.course_event_id
by
SELECT ...
FROM course
JOIN course_event ON course_event.course_id = course.course_id
JOIN course_event_package_links
ON course_event_package_links.course_event_id = course_event.course_event_id
...
About your error message, are you sure course.course_id exists? Maybe it was replaced by course.course_code?