I have one heavy MySQL query with 12 LEFT JOIN and noticed that some of tables have InnoDB engine and some Aria.
I've attached EXPLAIN of this query and pointed engine types at image with corresponding letters I and A.
Does fact of different engines affects on query speed and how seriously? Does changing of engines types helps to optimize query execution?
What else I could do to optimize this query?
Query (if needed)
SELECT user.id, user.first_name, user.last_name, user.birthday, user.email, user.phone, user.address_id,
user.alt_address_id, user.type, user.level_id, user_level.level, user.consecutive_orders, user.orders_count,
user.code_id, user.period, user.preferences, user.is_pick_up, user.pickup_address_id, user.is_active,
user.first_delivery_date, user.change_delivery_date, user.eway_id, user.date_created,
user.rest_referral_discount as `rest_referral_discount`, user.rest_code_discount as `rest_code_discount`,
user.rest_code_box_discount as `rest_code_box_discount`, user.rest_code_mp_discount as `rest_code_mp_discount`,
user.rest_code_tup_discount as `rest_code_tup_discount`, user.nf_pantry_list, user.nf_next_weeks_menu,
user.nf_paused_reminder, user.nf_welcome, user.nf_expected_delivery_time,
user.nf_delivery, address_pickup.address as `pickup_address`, address.address, address.unit,
address.instructions, location.id location_id, location.postcode, location.suburb,
location_state.code state_code, delivery_area.delivery_area_window_id delivery_area_window_id,
delivery_area_by_location.fee delivery_fee_value, delivery_area_window.day delivery_day,
delivery_area_window.day_name_full delivery_day_name_full, delivery_area_window.window delivery_window,
user.delivery_area_id, user.alt_delivery_area_id, if (user.is_pick_up, 0, delivery_area.fee) delivery_fee,
if (user.type = 1 || user.type = 2, 5, 0) ondemand_fee, code.code code_name, code.amount code_amount,
code.value code_value, code.is_permanent is_code_permanent, code.repeat code_repeat, code.times code_times,
code.apply_to code_apply_to, code.valid_from code_valid_from, code.valid_until code_valid_until,
if (code_used.count > 0, 1, 0) is_code_used, if (code_used.count > 0, code_used.count, 0) code_used_count,
if (user.is_pick_up, IFNULL(delivery_area_by_location.topup_available, 0), IFNULL(delivery_area.topup_available, 0)) topup_available,
(SELECT `order`.`id` FROM `order` LEFT JOIN `gift` ON gift.order_id = order.id
WHERE (`order`.`delivery_date` BETWEEN '2021-02-07' and '2021-02-13') and (user.id = order.user_id) and (`gift`.`id` IS NULL)
and (`order`.`status` = 10) ORDER BY `order`.`date_created` DESC LIMIT 1) as `order_id`,
(SELECT `order`.`delivery_date` FROM `order`
LEFT JOIN `gift`
ON gift.order_id = order.id
WHERE (user.id = order.user_id) and (`gift`.`id` IS NULL) and (`order`.`status` = 10) ORDER BY `order`.`date_created` DESC LIMIT 1) as `last_order_delivery_date`
FROM `user`
LEFT JOIN `address`
ON user.address_id = address.id
LEFT JOIN `address_pickup`
ON user.pickup_address_id = address_pickup.id
LEFT JOIN `delivery_area`
ON user.delivery_area_id = delivery_area.id
LEFT JOIN `delivery_area_window`
ON delivery_area_window.id = delivery_area.delivery_area_window_id
LEFT JOIN `user_level`
ON user.level_id = user_level.id
LEFT JOIN `location`
ON address.location_id = location.id
LEFT JOIN `location_state`
ON location.state_id = location_state.id
LEFT JOIN `delivery_area` `delivery_area_by_location` ON delivery_area_by_location.location_id = location.id
LEFT JOIN (SELECT count(*) count, `user_id`, `code_id` FROM `order` WHERE (code_id > 0) and (`order`.`status` = 10) GROUP BY `user_id`, `code_id`) `code_used`
ON ((user.id = code_used.user_id) and (code_used.code_id = user.code_id))
LEFT JOIN `code`
ON user.code_id = code.id WHERE (`user`.`type` = 0) and (`user`.`status` = 10)
GROUP BY `user`.`id` ORDER BY `last_name` LIMIT 15
UPD: CREATE TABLE
CREATE TABLE `address` (
`id` int(11) UNSIGNED NOT NULL,
`location_id` int(11) UNSIGNED NOT NULL,
`address` text NOT NULL,
`unit` char(4) NOT NULL,
`instructions` text NOT NULL,
`regular` tinyint(1) NOT NULL DEFAULT '1',
`topup` tinyint(1) NOT NULL DEFAULT '1',
`date_from` date DEFAULT NULL,
`date_to` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `address_pickup` (
`id` tinyint(3) UNSIGNED NOT NULL,
`address` text NOT NULL
) ENGINE=Aria DEFAULT CHARSET=utf8;
CREATE TABLE `code` (
`id` smallint(6) UNSIGNED NOT NULL,
`code` varchar(255) NOT NULL,
`amount` decimal(7,2) NOT NULL,
`value` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0 - number; 1 - percent',
`is_mswa` tinyint(4) DEFAULT '0',
`is_permanent` tinyint(4) DEFAULT '0',
`repeat` tinyint(4) DEFAULT '0',
`apply_to` tinyint(4) DEFAULT '0' COMMENT '0 - both; 1 - box; 2 - mp;',
`times` int(11) NOT NULL DEFAULT '0',
`date_created` datetime NOT NULL,
`date_updated` datetime NOT NULL,
`valid_from` date NOT NULL,
`valid_until` date DEFAULT NULL,
`author` varchar(255) NOT NULL,
`checkout_text` text NOT NULL,
`status` smallint(6) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `delivery_area` (
`id` int(10) UNSIGNED NOT NULL,
`location_id` int(11) NOT NULL,
`fee` decimal(7,2) NOT NULL DEFAULT '0.00',
`delivery_area_window_id` tinyint(4) UNSIGNED NOT NULL DEFAULT '1',
`topup_available` tinyint(1) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `delivery_area_window` (
`id` tinyint(4) UNSIGNED NOT NULL,
`day` tinyint(3) UNSIGNED NOT NULL,
`day_name` varchar(255) NOT NULL,
`day_name_full` varchar(255) NOT NULL,
`window` varchar(255) NOT NULL DEFAULT '',
`pickup` tinyint(4) NOT NULL DEFAULT '0'
) ENGINE=Aria DEFAULT CHARSET=utf8;
CREATE TABLE `gift` (
`id` int(11) UNSIGNED NOT NULL,
`user_id` int(11) UNSIGNED NOT NULL,
`recipient_id` int(11) UNSIGNED NOT NULL,
`type` tinyint(1) NOT NULL COMMENT '0 - card; 1 - box;',
`message` text NOT NULL,
`token` char(24) DEFAULT NULL,
`order_id` int(11) UNSIGNED NOT NULL,
`is_redeemed` tinyint(1) NOT NULL,
`date_exp` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `location` (
`id` int(10) UNSIGNED NOT NULL,
`postcode` int(4) UNSIGNED NOT NULL,
`suburb` varchar(45) NOT NULL,
`dc` varchar(45) NOT NULL,
`state_id` tinyint(3) UNSIGNED NOT NULL,
`type_id` tinyint(4) UNSIGNED NOT NULL,
`lat` double DEFAULT NULL,
`lon` double DEFAULT NULL
) ENGINE=Aria DEFAULT CHARSET=utf8;
CREATE TABLE `location_state` (
`id` tinyint(4) UNSIGNED NOT NULL,
`code` char(3) NOT NULL,
`state` varchar(255) NOT NULL
) ENGINE=Aria DEFAULT CHARSET=utf8;
CREATE TABLE `order` (
`id` int(11) UNSIGNED NOT NULL,
`user_id` int(11) UNSIGNED NOT NULL,
`shipping_address_id` int(11) UNSIGNED NOT NULL,
`topup_address_id` int(10) UNSIGNED NOT NULL,
`pickup_address_id` tinyint(3) UNSIGNED DEFAULT NULL,
`preferences` int(11) UNSIGNED NOT NULL,
`referral_discount` decimal(7,2) NOT NULL DEFAULT '0.00',
`code_id` int(11) UNSIGNED NOT NULL,
`code_discount` decimal(7,2) NOT NULL DEFAULT '0.00',
`pickup_discount` decimal(7,2) NOT NULL DEFAULT '0.00',
`admin_discount` decimal(7,2) NOT NULL DEFAULT '0.00',
`level_discount` decimal(7,2) NOT NULL DEFAULT '0.00',
`delivery_fee` decimal(7,2) NOT NULL DEFAULT '0.00',
`topup_delivery_fee` decimal(7,2) NOT NULL,
`ondemand_fee` decimal(7,2) NOT NULL DEFAULT '0.00',
`amount` decimal(7,2) NOT NULL DEFAULT '0.00',
`retry_payment` tinyint(3) UNSIGNED NOT NULL DEFAULT '0' COMMENT '1-wait answer; 2-recharge with sms; 3-recharge without sms',
`retry_payment_sms` int(11) UNSIGNED NOT NULL DEFAULT '0' COMMENT '0 - processed; >0 - sms id',
`retry_payment_email` int(10) UNSIGNED NOT NULL DEFAULT '0',
`eway_errors` text NOT NULL,
`date_created` datetime NOT NULL,
`date_updated` datetime NOT NULL,
`delivery_date` date DEFAULT NULL,
`status` smallint(6) UNSIGNED NOT NULL DEFAULT '10',
`processing_status` smallint(6) UNSIGNED NOT NULL,
`processing_status_edited` tinyint(1) UNSIGNED NOT NULL DEFAULT '0',
`has_topup` tinyint(1) UNSIGNED NOT NULL DEFAULT '0',
`is_topup_only` tinyint(1) UNSIGNED NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
CREATE TABLE `user` (
`id` int(11) UNSIGNED NOT NULL,
`first_name` varchar(255) NOT NULL,
`last_name` varchar(255) NOT NULL,
`birthday` date DEFAULT NULL,
`auth_key` varchar(32) NOT NULL,
`password_hash` varchar(255) NOT NULL,
`password_reset_token` varchar(255) DEFAULT NULL,
`email` varchar(255) NOT NULL,
`phone` varchar(255) DEFAULT NULL,
`custom_ref_code` varchar(255) DEFAULT NULL,
`eway_id` bigint(20) UNSIGNED DEFAULT NULL COMMENT 'eWAY Customer Token ID',
`active_campaign_id` int(11) UNSIGNED DEFAULT NULL COMMENT 'ActiveCampaign subscriber_id',
`level_id` tinyint(4) UNSIGNED NOT NULL DEFAULT '1',
`address_id` int(11) UNSIGNED NOT NULL DEFAULT '0',
`delivery_area_id` int(10) UNSIGNED DEFAULT NULL,
`alt_address_id` int(10) UNSIGNED DEFAULT NULL,
`alt_delivery_area_id` int(10) UNSIGNED DEFAULT NULL,
`code_id` int(11) UNSIGNED NOT NULL DEFAULT '0',
`period` tinyint(4) UNSIGNED NOT NULL DEFAULT '1' COMMENT '1 - Once a Week; 2 - Fortnightly',
`preferences` int(11) UNSIGNED NOT NULL DEFAULT '0',
`is_pick_up` tinyint(1) UNSIGNED NOT NULL DEFAULT '0',
`pickup_address_id` tinyint(3) UNSIGNED DEFAULT NULL,
`is_active` tinyint(4) NOT NULL DEFAULT '1' COMMENT '0 - Inactive; 1 - Active; -1 - Blocked',
`status` smallint(6) NOT NULL DEFAULT '10',
`type` tinyint(4) UNSIGNED NOT NULL COMMENT '0 - Set And Forget; 1 - On Demand; 2 - Trial; 3 - Potential;',
`first_delivery_date` date DEFAULT NULL,
`last_delivery_date` date DEFAULT NULL,
`change_delivery_date` date DEFAULT NULL,
`nf_pantry_list` tinyint(1) NOT NULL DEFAULT '1',
`nf_next_weeks_menu` tinyint(1) NOT NULL DEFAULT '1',
`nf_paused_reminder` tinyint(1) NOT NULL DEFAULT '1',
`nf_expected_delivery_time` tinyint(1) NOT NULL DEFAULT '1',
`nf_delivery` tinyint(1) NOT NULL DEFAULT '1',
`nf_welcome` tinyint(1) NOT NULL DEFAULT '1',
`date_created` datetime NOT NULL,
`date_updated` datetime NOT NULL,
`consecutive_orders` smallint(5) UNSIGNED DEFAULT NULL,
`orders_count` smallint(5) UNSIGNED NOT NULL DEFAULT '0',
`rest_referral_discount` decimal(7,2) UNSIGNED NOT NULL,
`rest_code_discount` decimal(7,2) UNSIGNED NOT NULL,
`rest_code_box_discount` decimal(7,2) UNSIGNED NOT NULL,
`rest_code_mp_discount` decimal(7,2) UNSIGNED NOT NULL,
`rest_code_tup_discount` decimal(7,2) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_level` (
`id` int(11) NOT NULL,
`level` varchar(255) NOT NULL,
`icon` varchar(255) NOT NULL,
`description` text NOT NULL,
`from` int(11) NOT NULL DEFAULT '0',
`to` int(11) NOT NULL DEFAULT '0',
`discount` int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
And indexes
--
-- Indexes table `address`
--
ALTER TABLE `address`
ADD PRIMARY KEY (`id`),
ADD KEY `location_id` (`location_id`),
ADD KEY `regular` (`regular`),
ADD KEY `topup` (`topup`),
ADD KEY `date_to` (`date_to`),
ADD KEY `date_from` (`date_from`);
--
-- Indexes table `address_pickup`
--
ALTER TABLE `address_pickup`
ADD PRIMARY KEY (`id`);
--
-- Indexes table `code`
--
ALTER TABLE `code`
ADD PRIMARY KEY (`id`),
ADD KEY `status` (`status`),
ADD KEY `valid_from` (`valid_from`),
ADD KEY `valid_until` (`valid_until`),
ADD KEY `date_created` (`date_created`),
ADD KEY `code` (`code`) USING BTREE,
ADD KEY `is_mswa` (`is_mswa`);
--
-- Indexes table `delivery_area`
--
ALTER TABLE `delivery_area`
ADD PRIMARY KEY (`id`),
ADD KEY `day` (`delivery_area_window_id`),
ADD KEY `location_id` (`location_id`) USING BTREE,
ADD KEY `friday_topup_available` (`topup_available`);
--
-- Indexes table `delivery_area_window`
--
ALTER TABLE `delivery_area_window`
ADD PRIMARY KEY (`id`),
ADD KEY `day` (`day`),
ADD KEY `pickup_only` (`pickup`);
--
-- Indexes table `gift`
--
ALTER TABLE `gift`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `token` (`token`),
ADD KEY `user_id` (`user_id`),
ADD KEY `recipient_id` (`recipient_id`),
ADD KEY `order_id` (`order_id`),
ADD KEY `is_redeemed` (`is_redeemed`);
--
-- Indexes table `location`
--
ALTER TABLE `location`
ADD PRIMARY KEY (`id`),
ADD KEY `idx_lon` (`lon`),
ADD KEY `idx_lat` (`lat`),
ADD KEY `type_id` (`type_id`),
ADD KEY `state_id` (`state_id`),
ADD KEY `postcode` (`postcode`),
ADD KEY `suburb_2` (`suburb`),
ADD KEY `postcode_suburb` (`postcode`,`suburb`) USING BTREE;
ALTER TABLE `location` ADD FULLTEXT KEY `suburb` (`suburb`);
--
-- Indexes table `location_state`
--
ALTER TABLE `location_state`
ADD PRIMARY KEY (`id`);
--
-- Indexes table `order`
--
ALTER TABLE `order`
ADD PRIMARY KEY (`id`),
ADD KEY `client_id` (`user_id`),
ADD KEY `status` (`status`),
ADD KEY `shipping_address_id` (`shipping_address_id`),
ADD KEY `preferences` (`preferences`),
ADD KEY `processing_status` (`processing_status`),
ADD KEY `date_created` (`date_created`),
ADD KEY `delivery_date` (`delivery_date`),
ADD KEY `pickup_address_id` (`pickup_address_id`),
ADD KEY `processing_status_edited` (`processing_status_edited`),
ADD KEY `retry_payment_sms` (`retry_payment_sms`),
ADD KEY `retry_payment` (`retry_payment`),
ADD KEY `retry_payment_email` (`retry_payment_email`),
ADD KEY `has_topup` (`has_topup`),
ADD KEY `is_topup_only` (`is_topup_only`),
ADD KEY `friday_address_id` (`topup_address_id`),
ADD KEY `code_id` (`code_id`),
ADD KEY `user_id` (`user_id`);
--
-- Indexes table `user`
--
ALTER TABLE `user`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `password_reset_token` (`password_reset_token`),
ADD KEY `level_id` (`level_id`),
ADD KEY `eway_id` (`eway_id`),
ADD KEY `password_hash` (`password_hash`),
ADD KEY `auth_key` (`auth_key`),
ADD KEY `email` (`email`),
ADD KEY `period` (`period`),
ADD KEY `preferences` (`preferences`),
ADD KEY `is_pick_up` (`is_pick_up`),
ADD KEY `is_active` (`is_active`),
ADD KEY `date_created` (`date_created`),
ADD KEY `phone` (`phone`) USING BTREE,
ADD KEY `active_campaign_id` (`active_campaign_id`),
ADD KEY `custom_ref_code` (`custom_ref_code`),
ADD KEY `consecutive_orders` (`consecutive_orders`),
ADD KEY `pickup_address_id` (`pickup_address_id`),
ADD KEY `rest_referral_discount` (`rest_referral_discount`),
ADD KEY `rest_code_discount` (`rest_code_discount`),
ADD KEY `rest_code_box_discount` (`rest_code_box_discount`),
ADD KEY `rest_code_mp_discount` (`rest_code_mp_discount`),
ADD KEY `delivery_area_id` (`delivery_area_id`),
ADD KEY `rest_code_tup_discount` (`rest_code_tup_discount`),
ADD KEY `orders_count` (`orders_count`),
ADD KEY `alt_delivery_address_id` (`alt_address_id`),
ADD KEY `alt_delivery_area_id` (`alt_delivery_area_id`),
ADD KEY `address_id` (`address_id`),
ADD KEY `code_id` (`code_id`),
ADD KEY `status` (`status`),
ADD KEY `type` (`type`),
ADD KEY `last_name` (`last_name`);
--
-- Indexes table `user_level`
--
ALTER TABLE `user_level`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT
--
ALTER TABLE `address`
MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `address_pickup`
MODIFY `id` tinyint(3) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `code`
MODIFY `id` smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `delivery_area`
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `delivery_area_window`
MODIFY `id` tinyint(4) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `gift`
MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `location`
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `location_state`
MODIFY `id` tinyint(4) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `order`
MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `user`
MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE `user_level`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
COMMIT;
For table order:
INDEX(status, code_id, order_id)
INDEX(status, order_id, code_id)
(I can't tell which would be better; the Optimizer can decide.)
Don't use LEFT JOIN when the 'right' table is not optional. It makes it tedious for a human (and the Optimizer) to figure the intent.
User needs
INDEX(type, status, code_id, code, id, last_name)
It is almost always beneficial to DROP INDEX(a) when you ADD INDEX(a,b). I bring that up because you probably have some one-column indexes.
If you need further help, please provide SHOW CREATE TABLE. I suspect that the query could be turned inside-out to great benefit. This involves finding the 15 ids first; then after that do all the JOINs.
That might have this as the first "derived" table since it generates only 15 rows, not the 9976 estimated in the Explain:
FROM ( SELECT id, `code`, code_id, last_name
FROM user
WHERE `type` = 0
AND `status` = 10
GROUP BY `id`
ORDER BY `last_name`
LIMIT 15
) AS u
JOIN ...
I have 3 tables:
pp088_project_tasks
CREATE TABLE IF NOT EXISTS `pp088_project_tasks` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`task_list_id` int(10) unsigned DEFAULT NULL,
`text` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`start_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`due_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`assigned_to_company_id` int(10) DEFAULT NULL,
`assigned_to_user_id` int(10) unsigned DEFAULT NULL,
`completed_on` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`completed_by_id` int(10) unsigned DEFAULT NULL,
`created_on` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_by_id` int(10) unsigned DEFAULT NULL,
`updated_on` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_by_id` int(10) unsigned DEFAULT NULL,
`order` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `task_list_id` (`task_list_id`),
KEY `completed_on` (`completed_on`),
KEY `created_on` (`created_on`),
KEY `order` (`order`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=76 ;
pp088_project_task_lists
CREATE TABLE IF NOT EXISTS `pp088_project_task_lists` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`milestone_id` int(10) unsigned NOT NULL DEFAULT '0',
`project_id` int(10) unsigned DEFAULT NULL,
`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`priority` int(3) unsigned NOT NULL DEFAULT '0',
`description` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`start_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`due_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`score` int(3) unsigned NOT NULL DEFAULT '0',
`is_private` tinyint(1) unsigned NOT NULL DEFAULT '0',
`completed_on` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`completed_by_id` int(10) unsigned DEFAULT NULL,
`created_on` datetime DEFAULT NULL,
`created_by_id` int(10) unsigned NOT NULL DEFAULT '0',
`updated_on` datetime DEFAULT NULL,
`updated_by_id` int(10) unsigned NOT NULL DEFAULT '0',
`order` tinyint(3) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `milestone_id` (`milestone_id`),
KEY `project_id` (`project_id`),
KEY `completed_on` (`completed_on`),
KEY `created_on` (`created_on`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
gantt_tasks
CREATE TABLE IF NOT EXISTS `gantt_tasks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`text` varchar(255) NOT NULL,
`start_date` date NOT NULL,
`duration` int(11) NOT NULL,
`progress` float NOT NULL DEFAULT '1',
`sortorder` int(11) NOT NULL,
`parent` int(11) NOT NULL,
`projectID` int(10) unsigned DEFAULT NULL,
`tipo_evento` varchar(100) NOT NULL,
`idPier` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=48 ;
I created an AFTER INSERT trigger on the 'pp088_project_tasks' table to insert into 'gantt_tasks'
CREATE TRIGGER `insert_gantt_task` AFTER INSERT ON `pp088_project_tasks`
FOR EACH ROW BEGIN
declare project_id int;
declare duracion int;
set project_id=(select project_id from pp088_project_task_lists where id=NEW.task_list_id);
set duracion=(select DATEDIFF(NEW.due_date,NEW.start_date));
insert into gantt_tasks (text,start_date,duration,projectID,idPier) values (NEW.text,NEW.start_date,duracion,project_id,NEW.id);
END
but the problem is with the setting of the project_id variable which sets the gantt_tasks field projectID to NULL because that query cannot retrieve the value using NEW.task_list_id, even if I use that value directly on the insert just to check the value it sets the gantt_tasks field projectID to 0......The strange thing is that if I use other values of the NEW they all work, it's just that field, the insert is successful for all of the other fields on gantt_tasks. I checked and the types are the same, and so the collation as well.
The first two tables are from a project manager called projectPier and the gantt_tasks table is one I created for a gantt chart(DHTMLX gantt chart).
... but the problem is with the setting of the project_id variable which sets the gantt_tasks field projectID to NULL because that query cannot retrieve the value using NEW.task_list_id, even if I use that value directly on the insert just to check the value it sets the gantt_tasks field projectID to 0
Reason is very much visible.
You have a variable project_id whose name matches that of a column in the table.
And when you use column name without a table qualifier, there arises a conflict on the names. And priority will be given to the local variable over column.
In your case, due to the statement
declare project_id int;
the default value of project_id would be zero. And hence, the output of the statement
set project_id=(select project_id from pp088_project_task_lists
where id=NEW.task_list_id);
would be a zero. And hence the same is used in the insert statement.
Options:
Change local variable name to something relevant.
Use table name to qualify the column name.
Sample Example: (using option 1)
Make following changes to your code and it should be working.
delimiter //
CREATE TRIGGER `insert_gantt_task` AFTER INSERT ON `pp088_project_tasks`
FOR EACH ROW BEGIN
declare _project_id int default 0;
declare _duracion int default 0;
select project_id into _project_id
from pp088_project_task_lists
where id = NEW.task_list_id;
select DATEDIFF( NEW.due_date, NEW.start_date ) into _duracion;
insert into gantt_tasks ( text, start_date, duration, projectID, idPier )
values( NEW.text, NEW.start_date, _duracion, _project_id, NEW.id );
END;
//
delimiter ;
Sample Example: (using option 2)
Make following changes to your code and it should be working.
delimiter //
CREATE TRIGGER `insert_gantt_task` AFTER INSERT ON `pp088_project_tasks`
FOR EACH ROW BEGIN
declare project_id int default 0;
declare duracion int default 0;
set project_id := ( select tl.project_id
from pp088_project_task_lists tl
where tl.id = NEW.task_list_id );
set duracion := select DATEDIFF( NEW.due_date, NEW.start_date );
insert into gantt_tasks ( text, start_date, duration, projectID, idPier )
values( NEW.text, NEW.start_date, duracion, project_id, NEW.id );
END;
//
delimiter ;