MySQL: Can this Join query be optimized? - mysql

I have two tables. create command for those tables are as follows
CREATE TABLE `invoice` (
`Id` bigint(20) NOT NULL,
`VersionNumber` int(11) NOT NULL,
`CreationDate` datetime default NULL,
`ModificationDate` datetime default NULL,
`CreateBy` bigint(20) default NULL,
`ModifyBy` bigint(20) default NULL,
`BusinessId` varchar(255) character set utf8 default NULL,
`Status` int(11) default NULL,
`VendorId` bigint(20) default NULL,
`CustomerId` bigint(20) default NULL,
`OrderDate` date default NULL,
`ExpectedDate` date default NULL,
`DeliveryDate` date default NULL,
`InvoiceFor` int(11) default NULL,
`Reference` varchar(255) character set utf8 default NULL,
`Agent` varchar(255) character set utf8 default NULL,
`BnAgent` varchar(255) character set utf8 default NULL,
`Note` varchar(255) character set utf8 default NULL,
`HasVoucher` char(1) character set utf8 default NULL,
PRIMARY KEY (`Id`),
KEY `CustomerId` (`CustomerId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `invoiceitem` (
`Id` bigint(20) NOT NULL,
`VersionNumber` int(11) NOT NULL,
`CreationDate` datetime default NULL,
`ModificationDate` datetime default NULL,
`CreateBy` bigint(20) default NULL,
`ModifyBy` bigint(20) default NULL,
`BusinessId` varchar(255) default NULL,
`Status` int(11) default NULL,
`InvoiceId` bigint(20) default NULL,
`ProductId` bigint(20) default NULL,
`PackageQty` decimal(19,5) default NULL,
`PackagePrice` decimal(19,5) default NULL,
`ItemPerPackage` decimal(19,5) default NULL,
`ItemQty` decimal(19,5) default NULL,
`ItemPrice` decimal(19,5) default NULL,
`StoreQty` decimal(19,5) default NULL,
`RevenuePercent` decimal(19,5) default NULL,
`PurchasePrice` decimal(19,5) default NULL,
`Vat` decimal(19,5) default NULL,
`TotalAmount` decimal(19,5) default NULL,
`InvoiceItemFor` int(11) default NULL,
`LifeTimeUptoDate` datetime default NULL,
PRIMARY KEY (`Id`),
KEY `invoiceid_productid` (`InvoiceId`,`ProductId`),
KEY `ProductId` (`ProductId`),
CONSTRAINT `FK_invoiceitem` FOREIGN KEY (`InvoiceId`) REFERENCES `invoice` (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Purpose of this query
I have to show the list of invoices to the admin. He need to see the invoice date, Invoice number, customer Id, Product id and if the customer take that product previously then that previous date.
Now the Query
SELECT iv.id, iv.CustomerId, ii.ProductId, MAX(iv2.orderdate) AS PriviousDate
FROM invoice AS iv
INNER JOIN invoice AS iv2
ON iv.CustomerId=iv2.CustomerId
AND iv.OrderDate>iv2.OrderDate
INNER JOIN invoiceItem AS ii
ON iv.id=ii.invoiceId
INNER JOIN invoiceItem AS ii2
ON iv2.id=ii2.invoiceId
AND ii.ProductId=ii2.ProductId
WHERE iv.Status=0
AND ii.Status=0
AND iv2.Status=0
AND ii2.Status=0
GROUP BY ii.ProductId, iv.CustomerId
Here iv.id and ii.id is primary key
customerId and Productid fields are also indexes
and invoiceId is the foreginkey (iv.id=ii.invoiceId )
I am running this query in my MySql server (local)
But Most of the time I got timeout. How can I optimized this query?
the Explain for this query is as follows:
now I apply
create index invoiceid_productid
on invoiceItem(invoiceId, productId)
after that the explain result is

Not much here (it would have been helpful to see what you're indexes are) but assuming the invoice ids increase in line with invoice date....I suspect this might be slightly faster:
SELECT iv.id, iv.CustomerId, ii.ProductId, MAX(iv2.orderdate) AS PriviousDate
FROM invoice AS iv
INNER JOIN invoice AS iv2
ON iv.CustomerId=iv2.CustomerId
AND iv.id>iv2.id
INNER JOIN invoiceItem AS ii
ON iv.id=ii.invoiceId
INNER JOIN invoiceItem AS ii2
ON iv2.id=ii2.invoiceId
AND ii.ProductId=ii2.ProductId
AND ii.invoiceId>ii2.invoiceId
WHERE iv.Status=0
AND ii.Status=0
AND iv2.Status=0
AND ii2.Status=0
GROUP BY ii.ProductId, iv.CustomerId
But you really need an index on ProductId, Status and InvoiceId in the invoiceItem table before it's going to be appreciable faster.

Looking at your EXPLAIN results, the problem is clearly the invoiceItem table. It has 200,000 rows, and MySQL isn't using any indexes to access it.
So you should look at creating indexes to speed access to it.
I mocked up your tables:
create table invoice (
id int auto_increment not null,
customerid int not null,
orderdate timestamp not null,
status int default 0 not null,
primary key(id)
);
create table invoiceItem (
id int auto_increment not null,
invoiceId int not null,
productId int not null,
status int default 0 not null,
primary key (id)
);
I created these indexes:
create index invoiceId on invoiceItem(invoiceId);
create index cod on invoice(customerid, orderdate);
create index stat on invoice(status);
My EXPLAIN (on empty tables) now has all tables using type ref.
You can also see this tutorial which is for MySQL ;-)

Related

How to use MYSQL JOIN structure? and how to optimize query time

I have a few problems with MYSQL database that I can't solve.
My query below is taking too much time and making the system hang. I'm trying to use the "JOIN" construct to develop this. But this time my aggregation, which I'm trying to do with "SUM", reduces the query to one line. Is it ok to do this job with "JOIN"? or how should i improve this query.
This database works with a total of 22 client devices in ASP .NET application. As I mentioned above, in cases where the query time is long, when the client devices send a query to the database at the same time, the client device freezes. What I don't understand is why a query in the browser app is making all devices wait. Isn't each query processed as a separate "Thread" in MYSQL? So if a query has a return time of 10 seconds, will all clients wait 10 seconds for the query to be answered in the browser?
SELECT *,
(SELECT MachModel FROM machine WHERE MachCode=workorder.MachCode) AS MachModel,
(SELECT RawMaterialDescription FROM rawmaterials WHERE RawMaterialCode=workorder.ProductRawMaterial) AS RawMaterialDescr,
(SELECT RawMaterialColor FROM rawmaterials WHERE RawMaterialCode=workorder.ProductRawMaterial) AS RawMaterialColor,
(SELECT StaffName FROM staff WHERE AccountName=workorder.AssignStaff) AS AssignStaffName,
(SELECT StaffCode FROM staff WHERE AccountName=workorder.AssignStaff) AS AssignStaffCode,
(SELECT MachStatus FROM machine WHERE MachCode=workorder.MachCode) AS MachStatus,
(SELECT SUM(xStopTime) FROM workorderb WHERE xWoNumber=workorder.WoNumber) AS WoTotalStopTime
FROM workorder
WHERE WoStatus=3
ORDER BY PlanProdStartDate DESC, WoSortNumber, WoNumber LIMIT 100
SELECT workorder.*,machine.MachModel,machine.MachStatus,rawmaterials.RawMaterialDescription,rawmaterials.RawMaterialColor,staff.StaffName,staff.StaffCode,SUM(workorderb.xStopTime)
FROM workorder
LEFT JOIN machine ON machine.MachCode=workorder.MachCode
LEFT JOIN rawmaterials ON rawmaterials.RawMaterialCode=workorder.ProductRawMaterial
LEFT JOIN staff ON staff.AccountName=workorder.AssignStaff
LEFT JOIN workorderb ON workorderb.xWoNumber=workorder.WoNumber
WHERE workorder.WoStatus=3
ORDER BY workorder.PlanProdStartDate DESC, workorder.WoSortNumber, workorder.WoNumber LIMIT 100
CREATE TABLE `workorder` (
`WoNumber` varchar(20) NOT NULL,
`MachCode` varchar(15) NOT NULL,
`PlannedMoldCode` varchar(10) NOT NULL,
`PartyNumber` smallint(6) NOT NULL,
`PlanProdCycleTime` smallint(6) NOT NULL,
`CalAverageCycleTime` float(15,1) unsigned NOT NULL,
`ProductRawMaterial` varchar(30) NOT NULL,
`PlanProdStartDate` date NOT NULL,
`PlanProdFinishDate` int(10) unsigned NOT NULL,
`WoStartDate` datetime DEFAULT NULL,
`WoFinishDate` datetime DEFAULT NULL,
`WoWorkTime` int(10) unsigned NOT NULL,
`WoSystemProductivity` smallint(6) unsigned NOT NULL,
`AssignStaff` varchar(50) DEFAULT '',
`WoStatus` smallint(6) NOT NULL,
`WoSortNumber` int(10) unsigned NOT NULL,
`CycleCount` int(11) unsigned NOT NULL,
`ControlDate` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
`WoProductionStatus` smallint(6) NOT NULL DEFAULT '0',
`Creator` varchar(50) NOT NULL,
`Changer` varchar(50) NOT NULL,
`CreateDate` datetime NOT NULL,
PRIMARY KEY (`WoNumber`) USING BTREE,
KEY `WoNumber` (`WoNumber`) USING BTREE,
KEY `WoNumber_2` (`WoNumber`) USING BTREE,
KEY `WoNumber_3` (`WoNumber`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
CREATE TABLE `machine` (
`MachCode` varchar(15) NOT NULL,
`MachModel` varchar(30) NOT NULL,
`FirstProdDate` date NOT NULL,
`MachCapacity` smallint(6) NOT NULL,
`MachStatus` smallint(6) NOT NULL,
`NowMoldOnMach` varchar(10) NOT NULL DEFAULT '',
`NowMachOperator` varchar(50) NOT NULL DEFAULT '',
`NowWorkOrder` varchar(20) NOT NULL DEFAULT '',
`IPNumber` varchar(15) NOT NULL,
`Creator` varchar(50) NOT NULL,
`Changer` varchar(50) NOT NULL,
`ControlDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`OperatorLoginDate` datetime DEFAULT NULL,
`Message` varchar(500) DEFAULT NULL,
`MessageReaded` smallint(6) DEFAULT '0',
`StaffName` varchar(50) DEFAULT 'OSIS',
`StaffImage` varchar(255) DEFAULT '',
`StopDesc` varchar(30) DEFAULT 'OSIS',
`StopTime` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`MachCode`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
CREATE TABLE `rawmaterials` (
`RawMaterialCode` varchar(15) NOT NULL,
`RawMaterialDescription` varchar(30) NOT NULL,
`RawMaterialColor` varchar(30) NOT NULL,
PRIMARY KEY (`RawMaterialCode`) USING BTREE,
KEY `RawMaterialCode` (`RawMaterialCode`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
CREATE TABLE `staff` (
`StaffCode` varchar(15) DEFAULT NULL,
`StaffCardCode` varchar(10) DEFAULT NULL,
`StaffName` varchar(50) NOT NULL,
`StaffPassword` varchar(10) NOT NULL,
`StaffStatus` smallint(6) NOT NULL DEFAULT '2',
`StaffDateOfStart` date NOT NULL,
`StaffBirthDay` date DEFAULT NULL,
`StaffGender` varchar(5) DEFAULT NULL,
`StaffRoleA` smallint(6) NOT NULL,
`StaffEmail` varchar(100) NOT NULL,
`StaffImageLink` varchar(255) DEFAULT NULL,
`AccountName` varchar(50) NOT NULL,
`StaffRoleB` smallint(6) NOT NULL,
`StaffRoleD` smallint(6) NOT NULL,
`StaffRoleE` smallint(6) NOT NULL,
`StaffRoleC` smallint(6) NOT NULL,
`StaffRoleF` smallint(6) NOT NULL,
`StaffRoleG` smallint(6) NOT NULL,
`StaffRoleH` smallint(6) NOT NULL,
`StaffRoleI` smallint(6) NOT NULL,
`StaffRoleJ` smallint(6) NOT NULL,
`StaffRoleK` smallint(6) NOT NULL,
`StaffRoleL` smallint(6) NOT NULL,
`StaffRoleM` smallint(6) NOT NULL,
`StaffRoleN` smallint(6) NOT NULL,
`StaffConnection` smallint(6) NOT NULL DEFAULT '2',
`MachineWorked` varchar(15) DEFAULT NULL,
`WorkOrderWorked` varchar(20) DEFAULT NULL,
`StaffGroup` varchar(50) NOT NULL,
`Creator` varchar(50) NOT NULL,
`Changer` varchar(50) DEFAULT NULL,
PRIMARY KEY (`AccountName`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
CREATE TABLE `workorderb` (
`xWoNumber` varchar(20) NOT NULL,
`xMachCode` varchar(15) NOT NULL,
`xPlannedMoldCode` varchar(10) NOT NULL,
`xPartyNumber` smallint(6) NOT NULL,
`xStaffName` varchar(50) NOT NULL,
`xStopCode` smallint(6) NOT NULL,
`xStopStartTime` datetime NOT NULL,
`xStopFinishTime` datetime DEFAULT NULL,
`xStopTime` int(11) DEFAULT NULL,
PRIMARY KEY (`xMachCode`,`xStopStartTime`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC
Your query with the joins was nearly there: it was just missing a GROUP BYclause.
I have replaced workorder.* with workorder.WoNumber in the SELECT and added GROUP BY workorder.WoNumber.
You can add as many columns from workorder in the SELECT as you like but you must list them in the GROUP BY.
SELECT workorder.WoNumber,machine.MachModel,machine.MachStatus,rawmaterials.RawMaterialDescription,rawmaterials.RawMaterialColor,staff.StaffName,staff.StaffCode,SUM(workorderb.xStopTime)
FROM workorder
LEFT JOIN machine ON machine.MachCode=workorder.MachCode
LEFT JOIN rawmaterials ON rawmaterials.RawMaterialCode=workorder.ProductRawMaterial
LEFT JOIN staff ON staff.AccountName=workorder.AssignStaff
LEFT JOIN workorderb ON workorderb.xWoNumber=workorder.WoNumber
WHERE workorder.WoStatus=3
GROUP BY workorder.WoNumber \* <<= ADD OTHER COLUMNS HERE AS NEEDED *\
ORDER BY workorder.PlanProdStartDate DESC, workorder.WoSortNumber, workorder.WoNumber LIMIT 100;
db<>fiddle here
Use InnoDB, not MyISAM. MyISAM locks the entire table when INSERTing; InnoDB can often allow other threads to run when inserting.
Other notes
workorder has 4 identical indexes on wonumber; keep the PK, toss the rest. Note that a PRIMARY KEY is an index. Check the other tables for redundant Keys.
Do you need the mixture of DESC and ASC in ORDER BY PlanProdStartDate DESC, WoSortNumber, WoNumber? If not, there may be an optimization here.
As Kendle suggests, JOINs would be faster since there are cases where the same table is needed twice. If values might be missing, then LEFT might be useful; it won't change the performance.
Needed:
workorderb: INDEX(xWoNumber, xStopTime)
Is xStopTime an elapsed time? Or a time of day?

Subquery returning null

Got this confusing issue where I need to get data from several tables and join them into one result.
This query was working fine:
select simcard.*,customer.name as cuname,mi,ma,co, tot from simcard, customer,
(SELECT s.sim_id AS ssim_id, min(datetime) AS mi, max(datetime) AS ma, FLOOR(sum(t.WEIGHT) / 1000) AS tot,
(SELECT count(datetime)
FROM transactions t
WHERE (t.SIM_ID = ssim_id) AND t.ROWTYPE LIKE '$D' GROUP BY t.sim_id) as co
FROM simcard s, transactions t
WHERE (s.sim_id = t.sim_id) AND t.ROWTYPE LIKE '$Z'
AND ( s.customer_id =1 ) GROUP BY s.sim_id) as T
WHERE (sim_id = ssim_id) AND (simcard.customer_id = customer.id) GROUP BY simcard.SIM_ID
But when I add a new customer and new simcard to that customer, it will return empty. I'm guessing this is because there is not transaction with that sim_id in the transaction able.
I've tried to left join but I'm just getting errors.
I've narrowed it down to the first subquery, removing the second one did not result in an non-empty result, but because both subqueries uses the transaction table I'm guessing that both will need some left join.
Structure:
DROP TABLE IF EXISTS `customer`;
CREATE TABLE IF NOT EXISTS `customer` (
`ID` int(10) NOT NULL AUTO_INCREMENT,
`NAME` varchar(40) DEFAULT NULL,
`API` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`ID`),
KEY `CUSTOMER_ID` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellstruktur `simcard`
--
DROP TABLE IF EXISTS `simcard`;
CREATE TABLE IF NOT EXISTS `simcard` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`SIM_ID` char(20) DEFAULT NULL,
`CUSTOMER_ID` char(10) DEFAULT NULL,
`SCALES_ID` char(10) DEFAULT NULL,
`NAME` varchar(40) DEFAULT NULL,
`ACTIVE` char(1) DEFAULT 'N',
`EMAIL` varchar(255) DEFAULT NULL,
`TARGET_WEIGHT` varchar(255) DEFAULT NULL,
`LICENSE` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`ID`),
KEY `SIM_ID` (`SIM_ID`),
KEY `CUSTOMER_ID` (`CUSTOMER_ID`),
KEY `SCALES_ID` (`SCALES_ID`),
KEY `SIM_ID_2` (`SIM_ID`,`CUSTOMER_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Tabellstruktur `transactions`
--
DROP TABLE IF EXISTS `transactions`;
CREATE TABLE IF NOT EXISTS `transactions` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`SCALES_ID` char(10) DEFAULT NULL,
`SIM_ID` char(20) DEFAULT NULL,
`ROWTYPE` char(2) DEFAULT NULL,
`DATETIME` datetime DEFAULT NULL,
`TRANSACTIONTIME` int(11) DEFAULT NULL,
`NAME` varchar(255) DEFAULT NULL,
`TRANSACTIONNUMBER` int(11) DEFAULT NULL,
`DATA0` varchar(255) DEFAULT NULL,
`DATA1` varchar(255) DEFAULT NULL,
`DATA2` varchar(255) DEFAULT NULL,
`DATA3` varchar(255) DEFAULT NULL,
`DATA4` varchar(255) DEFAULT NULL,
`DATA5` varchar(255) DEFAULT NULL,
`DATA6` varchar(255) DEFAULT NULL,
`DATA7` varchar(255) DEFAULT NULL,
`DATA8` varchar(255) DEFAULT NULL,
`MEMORY` varchar(255) DEFAULT NULL,
`MATERIAL` varchar(255) DEFAULT NULL,
`DENSITY` int(11) DEFAULT NULL,
`VEHICLETYPE` char(1) DEFAULT NULL,
`TOOLNAME` varchar(255) DEFAULT NULL,
`WEIGHT` int(11) DEFAULT NULL,
`TRANSACTIONID` int(11) DEFAULT NULL,
`group_id` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`ID`),
KEY `SIM_ID` (`SIM_ID`),
KEY `TRANSACTIONID` (`TRANSACTIONID`),
KEY `SCALES_ID` (`SCALES_ID`),
KEY `SIM_ID_2` (`SIM_ID`,`TRANSACTIONID`),
KEY `idx_transactions_ROWTYPE` (`ROWTYPE`),
KEY `idx_transactions_DATETIME` (`DATETIME`),
KEY `idx_transactions_DATA0` (`DATA0`),
KEY `idx_transactions_DATA1` (`DATA1`),
KEY `idx_transactions_DATA2` (`DATA2`),
KEY `idx_transactions_DATA3` (`DATA3`),
KEY `idx_transactions_DATA4` (`DATA4`),
KEY `idx_transactions_DATA5` (`DATA5`),
KEY `idx_transactions_DATA6` (`DATA6`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
COMMIT;
Expected result:
ID SIM_ID CUSTOMER_ID SCALES_ID NAME ACTIVE EMAIL TARGET_WEIGHT LICENSE cuname mi ma co tot
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
8 10100421287868 1 61 M-61M Y NULL NULL 0 testcustomer 2018-04-26 00:00:00 2018-08-08 00:00:00 14908 529446

select from two tables each with different join

Trying to run this query will not return any error but I guess there is still something wrong in it. After four minutes running it keeps elaborating:
SELECT DISTINCT azioni_row.id_az, sofferenze.Descrizione, COUNT(crediti.stato = 'aperta') as aperti, COUNT(crediti.stato = 'chiusa') as chiusi
FROM (`azioni_row`, sofferenze)
JOIN crediti ON azioni_row.id_cred=crediti.id_cre
JOIN azioni_head as ah1 ON azioni_row.id_az=ah1.id_az
JOIN azioni_head as ah2 ON ah2.id_soff = sofferenze.id_soff
GROUP BY id_az
ORDER BY `azioni_row`.`id_az` ASC
If I remove sofferenze.Descrizione from the select list and sofferenze from the FROM list it runs in a few seconds:
SELECT DISTINCT azioni_row.id_az, COUNT(crediti.stato = 'aperta') as aperti, COUNT(crediti.stato = 'chiusa') as chiusi
FROM azioni_row
JOIN crediti ON azioni_row.id_cred=crediti.id_cre
JOIN azioni_head as ah1 ON azioni_row.id_az=ah1.id_az
GROUP BY id_az
ORDER BY `azioni_row`.`id_az` ASC
I would like to show the Descrizione field but the link for it is in the head table, not in the row one. The relationship between head and row is a one to many. I store in head all the info that is not necessary to repeat for each row and the link with Descrizione is one of these fields.
EDIT:
this is the explain:
this is the create for azioni_head:
CREATE TABLE `azioni_head` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tipo` varchar(2) NOT NULL,
`id_az` varchar(11) NOT NULL,
`id_soff` varchar(11) NOT NULL,
`id_soff_gar` varchar(11) DEFAULT NULL,
`date_from` date NOT NULL,
`date_to` date NOT NULL,
`close_why` int(11) NOT NULL,
`RGE` varchar(30) NOT NULL,
`procedente` varchar(2) NOT NULL,
`curatore` varchar(11) NOT NULL,
`legale` varchar(11) NOT NULL,
`tribunale` varchar(11) NOT NULL,
`riparto` varchar(2) NOT NULL DEFAULT '0',
`perc_worst` decimal(13,10) NOT NULL,
`perc_best` decimal(13,10) NOT NULL,
`perc_poster` decimal(13,10) NOT NULL,
`attivo_storico` decimal(65,2) NOT NULL,
`passivo_storico` decimal(65,2) NOT NULL,
`attivo_storico_comm` decimal(65,2) NOT NULL,
`passivo_storico_comm` decimal(65,2) NOT NULL,
`acconti` decimal(65,2) NOT NULL,
`acconti_comm` decimal(65,2) NOT NULL,
`numero_comm` int(11) NOT NULL,
`legali_worst` decimal(65,2) NOT NULL,
`legali_best` decimal(65,2) NOT NULL,
`manuale` tinyint(1) NOT NULL DEFAULT '0',
`created_by` int(11) NOT NULL,
`created_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1449 DEFAULT CHARSET=utf8 COMMENT='tabella testata azioni'
this for azioni_row:
CREATE TABLE `azioni_row` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_az` varchar(11) NOT NULL,
`id_cred` varchar(11) NOT NULL,
`chiesto` decimal(65,2) NOT NULL,
`ammesso` decimal(65,2) NOT NULL,
`data_ammesso` date NOT NULL,
`rango_ammesso` tinytext NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4479 DEFAULT CHARSET=utf8
and this for sofferenze
CREATE TABLE `sofferenze` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_soff` varchar(11) NOT NULL,
`Descrizione` tinytext NOT NULL,
`gruppo` int(11) NOT NULL,
`cointestazione` int(11) NOT NULL,
`port_man` tinytext NOT NULL,
`head_port_man` tinytext NOT NULL,
`note` longtext NOT NULL,
`created_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`created_by` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
UNIQUE KEY `id_3` (`id`),
KEY `id_2` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1716 DEFAULT CHARSET=utf8
Please provide proper CREATE statements as well as the output of:
EXPLAIN
SELECT a.id_az
, s.Descrizione
, COUNT(c.stato = 'aperta') aperti
, COUNT(c.stato = 'chiusa') chiusi
FROM azioni_row a
JOIN sofferenze s
CROSS
JOIN crediti c
ON c.id_cre = a.id_cred
JOIN azioni_head ah1
ON ah1.id_az = a.id_az
JOIN azioni_head ah2
ON ah2.id_soff = s.id_soff
GROUP
BY a.id_az
, s.Descrizione
ORDER
BY a.id_az ASC
Edit: You seem to have lots of indexes on the same column. Drop all indexes except the PRIMARY KEYs, and create the following indexes:
sofferenze: id_soff
azioni_row: try a composite index on (id_az,id_cred)
azioni_head: an index on id_soff and an index on id_az
Crediti is missing so I can't comment on that one.

mysql join query is slow compared with mssql

I have the following simple join query
SELECT
count(*)
FROM
DBx.caseview p2015
INNER JOIN DBy.caseview p2014 ON p2015.casenumber=p2014.casenumber;
For some reason it just leaves MySQL hanging there for a lot of time until I get tired and cancel it. On the contrary, if run exactly the same code on MSSQL with the same data set the query takes a few seconds at most.
Is there a parameter that needs to be changed on MySQL to speed up this type of queries?
Here's my table in MySQL
CREATE TABLE `caseview` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`CASEID` varchar(18) DEFAULT NULL,
`CASENUMBER` int(10) DEFAULT NULL,
`ACCOUNTID` varchar(18) DEFAULT NULL,
`ACCOUNT` varchar(256) DEFAULT NULL,
`ASSETID` varchar(18) DEFAULT NULL,
`SAPPRODUCTGROUP` varchar(10) DEFAULT NULL,
`PRODUCT` varchar(128) DEFAULT NULL,
`FAMILY` varchar(128) DEFAULT NULL,
`CONTACTID` varchar(18) DEFAULT NULL,
`OWNERID` varchar(18) DEFAULT NULL,
`TYPE` varchar(128) DEFAULT NULL,
`PRIORITY` varchar(24) DEFAULT NULL,
`ORIGIN` varchar(24) DEFAULT NULL,
`SUBJECT` varchar(256) DEFAULT NULL,
`STATUS` varchar(24) DEFAULT NULL,
`LASTACTIVITY` varchar(1024) DEFAULT NULL,
`INITALDESCRIPTION` varchar(1024) DEFAULT NULL,
`CLOSEDDATE` datetime DEFAULT NULL,
`CREATEDDATE` datetime DEFAULT NULL,
`LASTMODIFIEDDATE` datetime DEFAULT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `ID_UNIQUE` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=122393 DEFAULT CHARSET=utf8;
There's two tables with exactly the same configuration as above, just different data
DBx.caseview p2015 has 197647 rows
DBy.caseview p2014 has 122392 rows
Create an Index for CASENUMBER field.
ALTER TABLE `caseview` ADD INDEX ( `CASENUMBER` ) ;
Give it a few seconds to create the index and run the query again.

Problems with a MySQL server change

I have three tables in MySQL:
CREATE TABLE `mlm`.`facturacion_2012_drm_base` ( `custid`
varchar(20) NOT NULL, `fecha` date NOT NULL, `docid` varchar(20)
NOT NULL, `billid` varchar(20) NOT NULL, `movimiento` varchar(20)
DEFAULT NULL, `movid` varchar(20) DEFAULT NULL, `medio_pago`
varchar(40) DEFAULT NULL, `digitos` varchar(20) DEFAULT NULL,
`monto_facturado` decimal(20,2) NOT NULL, `monto_pagado`
decimal(20,2) NOT NULL, `monto_usado` decimal(20,2) NOT NULL,
`documento` varchar(2) NOT NULL, `codigo_pago` varchar(5) DEFAULT
NULL, `desc_pago` varchar(100) DEFAULT NULL, `sociedad`
varchar(45) DEFAULT NULL, `sociedad_bonif` varchar(45) DEFAULT NULL,
KEY `billid` (`billid`), KEY `motors_no_fact`
(`custid`,`billid`,`fecha`,`documento`) USING BTREE, KEY
`facturacion` (`custid`,`fecha`,`documento`) USING BTREE )
ENGINE=MyISAM DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
CREATE TABLE `mlm`.`facturacion_2012_drm_cortes` ( `id` bigint(20)
NOT NULL AUTO_INCREMENT, `fecha_inicial` date NOT NULL,
`fecha_final` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM
AUTO_INCREMENT=433 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
CREATE TABLE `mlm`.`facturacion_2012_drm_emitidas` ( `id`
bigint(20) NOT NULL AUTO_INCREMENT, `custid` varchar(20) NOT NULL,
`fecha_emision` date NOT NULL, `id_fechas` bigint(20) NOT NULL,
`monto` decimal(20,2) NOT NULL, `iva` decimal(20,2) NOT NULL,
`total` decimal(20,2) NOT NULL, `medio_pago` varchar(2000) NOT NULL,
`digitos` varchar(100) NOT NULL, `operaciones` int(10) NOT NULL,
`activa` varchar(2) NOT NULL, `movimiento` varchar(45) NOT NULL,
`parcialidades` varchar(100) NOT NULL, `monto_bruto` decimal(20,2)
NOT NULL, `billid` varchar(45) NOT NULL, `serie` varchar(2)
DEFAULT NULL, `folio` int(10) DEFAULT NULL, `uuid` varchar(45)
DEFAULT NULL, PRIMARY KEY (`id`), KEY `motors`
(`billid`,`id_fechas`,`activa`) ) ENGINE=MyISAM AUTO_INCREMENT=511483
DEFAULT CHARSET=latin1;
I changed the MySQL server from 5.1 (32 Bits) to 5.6 (64 Bits) and restored all my tables but I´m having problems with this query:
SELECT a.custid,
a.monto_facturado,
a.billid,
a.fecha,
b.id,
b.fecha_inicial
FROM facturacion_2012_drm_base a,
facturacion_2012_drm_cortes b
WHERE a.custid = ANY (SELECT custid
FROM facturacion_motors_pendientes
WHERE situacion = 'no facturado')
AND a.billid <> ALL (SELECT billid
FROM facturacion_2012_drm_emitidas
WHERE activa = 'SI')
AND a.fecha BETWEEN b.fecha_inicial AND b.fecha_final
AND a.documento = 'FA'
AND Year(a.fecha) = Year(Curdate())
GROUP BY a.billid
Since the server change, the query never finish, showing the message "Query is being executed..."
Anybody knows why this is happening?
At the very least you have indexing problems:
On facturacion_2012_drm_emitidas you filter by activa but do not have an index that can be used for this
On facturacion_2012_drm_base you don't have an index for fecha or documento that can be used
On facturacion_2012_drm_cortes you don't have an index for fecha_inicial or fecha_final
I don't know if you have index problems on facturacion_motors_pendientes because you did not include DDL for it.
Make sure you have the proper indexes for your query and then see what happens. What is happening now is that you have a complex join with subqueries and basically none of it is utilizing indexes, requiring you to execute full table scans on all tables involved.
You also might consider converting these tables to InnoDB, as that is the preferred table type in 5.6. This is of course unless you need certain MyISAM functionality on these tables (like full text search).