How to speed up loading data from MySQL query with multiple joins - mysql

When I run this query it only displays loading that is not finished. So the time to run the query has run out without displaying any data. In fact, making computer operations become very slow.
Here is the problem. I am selecting and doing multiple joins to get the correct items... This query takes so long time. Anyone know how I can speed this up? Here is the query.
SELECT a.*,
LEFT(a.tgl_inovasi, 10) AS tgl_ino, b.`nm_unit`, c.`nm_inovasijns`,
d.`nm_regulasi`, e.`nm_sediasdm`, f.`nm_anggaran`, g.`nm_it`, h.`nm_bimtek`,
i.`nm_renstra`, j.`nm_jejaring`, k.`nm_replikasi`, l.`nm_pedoman`,
m.`nm_pengelola`, n.`nm_informasi`, o.`nm_penyelesaian`, p.`nm_partisipasi`,
q.`nm_kemudahaninf`, r.`nm_kemudahanpro`, s.`nm_online`, t.`nm_kecepatan`,
u.`nm_kemanfaatan`, v.`nm_kepuasan`, w.`nm_user`, x.nm_inovasikat
FROM inovasi a, unit b, inovasijns c, regulasi d, sediasdm e, anggaran f,
it g, bimtek h, renstra i, jejaring j, replikasi k, pedoman l, pengelola m,
informasi n, penyelesaian o, partisipasi p, kemudahaninf q, kemudahanpro r,
online s, kecepatan t, kemanfaatan u, kepuasan v, `user` w, inovasikat x
WHERE x.id_inovasikat = a.id_inovasikat AND w.`id_user` = a.`id_user` AND
v.`id_kepuasan` = a.`id_kepuasan` AND u.`id_kemanfaatan` = a.`id_kemanfaatan` AND
t.`id_kecepatan` = a.`id_kecepatan` AND s.`id_online` = a.`id_online` AND
r.`id_kemudahanpro` = a.`id_kemudahanpro` AND q.`id_kemudahaninf` =
a.`id_kemudahaninf` AND p.`id_partisipasi` = a.`id_partisipasi` AND
o.`id_penyelesaian` = a.`id_penyelesaian` AND n.`id_informasi` = a.`id_informasi`
AND m.`id_pengelola` = a.`id_pengelola` AND l.`id_pedoman` = a.`id_pedoman` AND
k.`id_replikasi` = a.`id_replikasi` AND j.`id_jejaring` = a.`id_jejaring` AND
i.`id_renstra` = a.`id_renstra` AND h.`id_bimtek` = a.`id_bimtek` AND g.`id_it` =
a.`id_it` AND f.`id_anggaran` = a.`id_anggaran` AND e.`id_sediasdm` =
a.`id_sediasdm` AND d.`id_regulasi` = a.`id_regulasi` AND c.`id_inovasijns` =
a.`id_inovasijns` AND b.`id_unit` = a.`id_unit` AND a.no_inovasi = '$no_inovasi'
I try looking for the solution from other threat, almost all of them suggest using an index. But I don't understand which tables and fields should be added to the index. Please help to solve this problem.
I already run this query :
CREATE INDEX idx_inovasi1 ON inovasi (no_inovasi, tgl_inovasi, satuan, id_unit, nm_kelompok, subjek, id_inovasijns, id_inovasikat, id_regulasi, regulasi_doc, id_sediasdm, sediasdm_doc);
but it still hasn't affected anything.

How about switching to left join's, using the modern JOIN syntax.
SELECT a.*
, LEFT(a.tgl_inovasi, 10) AS tgl_ino
, b.`nm_unit`
, c.`nm_inovasijns`
, d.`nm_regulasi`
, e.`nm_sediasdm`
, f.`nm_anggaran`
, g.`nm_it`
, h.`nm_bimtek`
, i.`nm_renstra`
, j.`nm_jejaring`
, k.`nm_replikasi`
, l.`nm_pedoman`
, m.`nm_pengelola`
, n.`nm_informasi`
, o.`nm_penyelesaian`
, p.`nm_partisipasi`
, q.`nm_kemudahaninf`
, r.`nm_kemudahanpro`
, s.`nm_online`
, t.`nm_kecepatan`
, u.`nm_kemanfaatan`
, v.`nm_kepuasan`
, w.`nm_user`
, x.nm_inovasikat
FROM inovasi a
LEFT JOIN unit b ON b.`id_unit` = a.`id_unit`
LEFT JOIN inovasijns c ON c.`id_inovasijns` = a.`id_inovasijns`
LEFT JOIN regulasi d ON d.`id_regulasi` = a.`id_regulasi`
LEFT JOIN sediasdm e ON e.`id_sediasdm` = a.`id_sediasdm`
LEFT JOIN anggaran f ON f.`id_anggaran` = a.`id_anggaran`
LEFT JOIN it g ON g.`id_it` = a.`id_it`
LEFT JOIN bimtek h ON h.`id_bimtek` = a.`id_bimtek`
LEFT JOIN renstra i ON i.`id_renstra` = a.`id_renstra`
LEFT JOIN jejaring j ON j.`id_jejaring` = a.`id_jejaring`
LEFT JOIN replikasi k ON k.`id_replikasi` = a.`id_replikasi`
LEFT JOIN pedoman l ON l.`id_pedoman` = a.`id_pedoman`
LEFT JOIN pengelola m ON m.`id_pengelola` = a.`id_pengelola`
LEFT JOIN informasi n ON n.`id_informasi` = a.`id_informasi`
LEFT JOIN penyelesaian o ON o.`id_penyelesaian` = a.`id_penyelesaian`
LEFT JOIN partisipasi p ON p.`id_partisipasi` = a.`id_partisipasi`
LEFT JOIN kemudahaninf q ON q.`id_kemudahaninf` = a.`id_kemudahaninf`
LEFT JOIN kemudahanpro r ON r.`id_kemudahanpro` = a.`id_kemudahanpro`
LEFT JOIN online s ON s.`id_online` = a.`id_online`
LEFT JOIN kecepatan t ON t.`id_kecepatan` = a.`id_kecepatan`
LEFT JOIN kemanfaatan u ON u.`id_kemanfaatan` = a.`id_kemanfaatan`
LEFT JOIN kepuasan v ON v.`id_kepuasan` = a.`id_kepuasan`
LEFT JOIN `user` w ON w.`id_user` = a.`id_user`
LEFT JOIN inovasikat x ON x.id_inovasikat = a.id_inovasikat
WHERE a.no_inovasi = '$no_inovasi'
As for the indexes. There's almost a whole alphabeth of tables linked.
Most are probably joined on the primary index.
So look at the defenition of those tables, and discover which tables don't have their PK joined.
Maybe those could benefit from an index on the field used in the query.

you should use indexes, check how to index fields, but above all index the fields you have after the "where"

If you add the results of the EXPLAIN (your SQL), it would be helpful to pinpoint issues.
https://dev.mysql.com/doc/refman/8.0/en/explain.html

Related

Mysql view are very slow

My mysql view is really slow in thousands of data how can we improve this functionality?
While fetch this view in 10000s data then it takes more than 30 sec. how could we revise this view table?
SELECT
i.jo_in_id,
j.*,
i.jo_in_week_number,
i.jo_in_client_ref_no,
i.cl_id AS jo_in_cl_id,
c.cl_short_name,
c.cl_business_name,
m.me_first_name,
m.me_last_name,
m.me_mobile,
sk.sk_name,
sk.sk_ticketed,
ti.ti_id,
ta.ta_name,
u.un_id,
u.un_from,
u.un_to,
v.ve_name,
mp.vmp_name,
r.vr_name
FROM
jo_2_no j2n,
jo_in_numbers i,
jobs j
LEFT JOIN venues_new v ON j.ve_id = v.ve_id
LEFT JOIN venues_meeting_place mp ON j.vmp_id = mp.vmp_id
LEFT JOIN venues_rooms r ON j.vr_id = r.vr_id
LEFT JOIN clients c ON j.cl_id = c.cl_id
LEFT JOIN members m ON j.me_id = m.me_id
LEFT JOIN skills sk ON j.sk_id = sk.sk_id
LEFT JOIN tasks ta ON j.ta_id = ta.ta_id
LEFT JOIN crew_tickets ti ON j.sk_id = ti.sk_id AND j.me_id = ti.me_id AND j.jo_time_off < ti.ti_expire
LEFT JOIN unavailability u ON j.me_id = u.me_id AND ((j.jo_time_on BETWEEN u.un_from AND u.un_to) OR (j.jo_time_on BETWEEN u.un_from AND u.un_to))
WHERE
j.jo_id = j2n.jo_id
AND j2n.jo_in_numbers_id = i.jo_in_id
AFTER user EXPLAIN SELECT following is the output
In your EXPLAIN, I see that your joined tables ti and u are read with table-scans (type: ALL). This is probably the biggest problem for your performance.
You should make sure you have the following indexes created:
ALTER TABLE crew_tickets ADD KEY (sk_id, me_id, ti_expire);
ALTER TABLE unavailability ADD KEY (me_id, un_from, un_to);
That should help the joins to those tables work with index lookups instead of table-scans. I think they'll be accessed as covering indexes, too.
Also, please don't use the outdated "comma-joins." Especially do not mix both styles. It will bite you when you get surprised by the order of precedence between comma-joins and JOIN operators. See examples in Can someone help explain why not using a SQL JOIN is bad practice and wrong? or Error on JOIN mysql.
Write your joins this way:
FROM jo_2_no j2n
INNER JOIN jo_in_numbers i ON j2n.jo_in_numbers_id = i.jo_in_id
INNER JOIN jobs j ON j.jo_id = j2n.jo_id
LEFT JOIN venues_new v ON j.ve_id = v.ve_id
LEFT JOIN venues_meeting_place mp ON j.vmp_id = mp.vmp_id
LEFT JOIN venues_rooms r ON j.vr_id = r.vr_id
LEFT JOIN clients c ON j.cl_id = c.cl_id
LEFT JOIN members m ON j.me_id = m.me_id
LEFT JOIN skills sk ON j.sk_id = sk.sk_id
LEFT JOIN tasks ta ON j.ta_id = ta.ta_id
LEFT JOIN crew_tickets ti ON j.sk_id = ti.sk_id
AND j.me_id = ti.me_id AND j.jo_time_off < ti.ti_expire
LEFT JOIN unavailability u ON j.me_id = u.me_id
AND j.jo_time_on BETWEEN u.un_from AND u.un_to
I removed the redundant term in the join condition for u. The optimizer might eliminate that logic, but why make it work so hard?

How do I make this complex query run faster?

This query is taking between 20-40 seconds to run. I need to speed it up greatly if possible.
SELECT DISTINCT a.category, a.key
FROM system_permissions AS a, system_permission_to_role AS b,
system_user_to_role AS c, system_users AS d
WHERE
(
(
a.system_permission_id=b.system_permission_id
AND (b.system_role_id=c.system_role_id || c.system_role_id = 0)
AND a.system_permission_id NOT IN (
SELECT system_permission_id FROM system_permission_exclusions AS f
WHERE d.system_user_id=f.system_user_id
)
AND c.system_user_id=d.system_user_id
)
OR a.system_permission_id IN (
SELECT system_permission_id
FROM system_permission_inclusions AS g
WHERE d.system_user_id=g.system_user_id
)
)
AND d.ldap_objectguid = '?';
The reason behind doing it this way is that I am creating exclusion and inclusion tables for permissions that fall outside of the standard defined roles, so first I need to exclude ones that are part of the role but exist in the exclusion table, then I need to add ones that are NOT part of their role, but exist in the inclusion table.
I am open to the idea of redesigning the tables also.
Does this work?
SELECT DISTINCT P.category, P.key
FROM system_users U
LEFT OUTER JOIN system_permission_inclusions PI ON PI.system_user_id = U.system_user_id
INNER JOIN system_user_to_role UR ON UR.system_user_id = U.system_user_id
INNER JOIN system_permission_to_role PR ON PR.system_role_id = UR.system_role_id
INNER JOIN system_permissions P ON P.system_permission_id = PR.system_permission_id OR P.system_permission_id = PI.system_permission_id
WHERE U.ldap_objectguid = '?'
AND P.system_permission_id NOT IN (SELECT system_permission_id FROM system_permission_exclusions WHERE system_user_id = U.system_user_id)

SQL join not working

I am trying to merge these two queries I have on a join but its not working out so well can you tell me where i'm going wrong. Thanks in advance
SELECT z1blto,
z1ctrk
FROM z1mast AS e
JOIN d
(
select a.ordprod,
a.ordtotpcs ,
a.ordordnum,
b.orhdate
FROM dta/dw30d a
JOIN dta/dw30c b
ON a.ordcust = b.orhcust
AND a.ordordnum = b.orhordnum
WHERE a.ordcust = 'GL02'
AND a.ordprod = '2002534B_GC'
ORDER BY b.orhdate) AS d
ON e.z1cucd = d.ordcust
Looks like you have a typo in your query. Your ON specification uses ordcust for a and orhcust for b, similarly for ordornum and orddate. Here is the corrected version. And you have an extra d before the nested query. I'm making some assumptions regarding spelling, as the information is missing from your questions.
SELECT z1blto,
z1ctrk
FROM z1mast AS e
JOIN
(
select a.ordprod,
a.ordtotpcs ,
a.ordordnum,
b.orddate
FROM dta/dw30d a
JOIN dta/dw30c b
ON a.ordcust = b.ordcust
AND a.ordordnum = b.ordordnum
WHERE a.ordcust = 'GL02'
AND a.ordprod = '2002534B_GC'
ORDER BY b.orddate) AS d
ON e.z1cucd = d.ordcust

Left join with multiple tables and conditions

I want to sort after a value in another table the current table is referenced to. My query looks like this:
SELECT o._id,
o.titel,
o.beschreibung
FROM `objekt` AS o,
`objekt_einzel` AS oe,
`objekt_einzel_immobilie` AS oei,
`objekt_art` AS oa,
`verortung` AS v
#here
,`person` AS p,
`person_bauträger` AS pb
#end
WHERE o._id = oe.objekt_id
AND oe._id = oei.objekt_einzel_id
AND oa._id = o.objekt_art_id
AND o.ort_id = v._id
#here
AND oe.bauträger_id = pb._id
AND pb.person_id = p._id
#end
AND ( oei.justimmo_objekt_id = "0"
OR oei.justimmo_objekt_id IS NULL
OR oei.justimmo_objekt_id = "" )
#here
ORDER BY p.firmenbezeichnung ASC
The query is working fine but it shows me only values if oe.bauträger_id is set. I also want the null values. So I need a left join. I tried different things but I only get messages like unknown column or I get too much results.
I tried to simplify it to this:
SELECT o._id,
o.titel,
o.beschreibung
FROM `objekt` AS o,
`objekt_einzel` AS oe,
(SELECT oe.bauträger_id
FROM objekt o, objekt_einzel oe, objekt_einzel_immobilie oei
WHERE o._id = oe.objekt_id AND oe._id = oei.objekt_einzel_id) AS menge1
LEFT JOIN
(SELECT pb._id AS bauträger_id
FROM person p, person_bauträger pb
WHERE p._id = pb.person_id) AS menge2
ON menge1.bauträger_id = menge2.bauträger_id
WHERE o._id = oe.objekt_id AND oe.bauträger_id = menge1.bauträger_id
but here I get a too big result set. I don't know how to explain this better. The data sets are too big to create an example. I hope you understand what I mean.
SELECT o._id,
o.titel,
o.beschreibung
FROM `objekt` AS o
JOIN `objekt_einzel` AS oe ON o._id = oe.objekt_id
JOIN `objekt_einzel_immobilie` AS oei ON oe._id = oei.objekt_einzel_id
JOIN `objekt_art` AS oa ON o.objekt_art_id = oa._id
JOIN `verortung` AS v ON o.ort_id = v._id
LEFT JOIN `person_bauträger` AS pb ON oe.bauträger_id = pb._id
LEFT JOIN `person` AS p ON pb.person_id = p._id
WHERE oei.justimmo_objekt_id = "0"
OR oei.justimmo_objekt_id IS NULL
OR oei.justimmo_objekt_id = ""
ORDER BY p.firmenbezeichnung ASC
This second try should work as it is just the original code rewritten using JOIN syntax and with LEFT JOINs.

Convert this SQL to HQL? (left join with values instead of columns)

I'm trying to convert this SQL to HQL, but I found no way to do that left join.
SELECT
mdcs_causa.id_causa,
usuarios.ds_usuario,
usuarios.setor,
empresas.ds_empresa,
itens_controle.id_item_controle,
itens_controle.ds_item,
itens_controle.ds_indicador,
itens_controle.ds_cliente,
itens_controle.desdobramento,
itens_controle.auxiliar,
itens_controle.bmk_nome,
itens_controle.bmk_vlr,
m.status,
m.medido,
m.medicao,
m.fca,
m.am_cronico,
m.ac_cronico,
m.ap_cronico,
m.id_medicoes as idmedicao,
itens_controle.prioridade
FROM
mdcs
INNER JOIN mdcs_causa
ON mdcs.id_mdc = mdcs_causa.id_mdc
INNER JOIN itens_controle
ON mdcs_causa.Id_Item_Controle = itens_controle.id_item_controle
INNER JOIN usuarios
ON usuarios.id_usuario = itens_controle.id_usuario
INNER JOIN empresas
ON empresas.id_empresa = usuarios.id_cliente_tabela
LEFT JOIN medicoes m
ON (
itens_controle.id_item_controle = m.id_item_controle
and
m.nm_ano = 2013
and
m.nm_periodo = 2
and
mdcs_causa.id_mdc = mdcs.id_mdc
)
WHERE
mdcs.id_mdc = 5077
I thought I could put the nm_ano and nm_periodo conditions in the where clause, with an OR to m.id_item_controle is null but this OR condition didn't seem to work, even in SQL.
Another approach was to left join a sub query. That worked in SQL, but I think HQL doesn't support that.
It can be done with with keyword:
...
left join itens_controle.medicoes m with (m.nm_ano = 2013 and m.nm_periodo = 2 and mdcs_causa.id_mdc = mdcs.id_mdc)
where mdcs.id_mdc = 5077
Instead of explicit values you should supply them as arguments.
Read this in this pdf left join is used
as below:
Query getEBills =session.createQuery( session.createQuery( from " EBill ebill EBill
ebill
left join ebill.accountTransaction where
ebill.balance > 500";
Li li f l bi i li () ist listOfRowValues = getDebitTransactions.list();
for (Object[] singleRowValues : listOfRowValues) {
// pull off the EBill // pull off the EBill
EBill ebill = (EBill)singleRowValues[0];
I dont have any experience in HQL, i have pasted what i have found for you. hope this will help you in any way.