Mysql innerjoin very slow - mysql

I have an SQL query that takes over 4 hours to complete.
The query is as follows
UPDATE carepathaction a1
INNER JOIN carepathaction a2
ON a1.sourceoid = a2.oid
INNER JOIN carepathgroup g
ON g.sourceoid = a2.carepathgroupoid
INNER JOIN carepathphase f
ON f.oid = g.carepathphaseoid
SET a1.carepathgroupoid = g.oid
WHERE f.code = 'EDIT'
He has to update 65000 items. Is there some optimalization i can do in this query?
CarePathAction
CREATE TABLE `carepathaction`
(
`oid` INT(11) NOT NULL,
`typeid` CHAR(1) NOT NULL DEFAULT 'X',
`sequencenumber` INT(11) NOT NULL,
`description` VARCHAR(1024) NOT NULL,
`duration` INT(11) NOT NULL comment 'In minutes',
`deadline` INT(11) NOT NULL comment
'# dagen in combinatie met deadlineType (sinds begin traject of sinds begin deze actie)'
,
`deadlinetype` INT(11) NOT NULL comment
'1) = deadline sinds zorgpad\n2) = deadline sinds start deze actie\n3) = deadline sinds zorgpadfase'
,
`repeatperweek` INT(11) DEFAULT NULL,
`numbertorepeat` INT(11) DEFAULT NULL,
`carepathoid` INT(11) DEFAULT NULL,
`usertaskoid` INT(11) DEFAULT NULL,
`templateattachment` VARCHAR(45) DEFAULT NULL,
`partyrolecategoryoid` INT(11) DEFAULT NULL,
`automatic` BIT(1) NOT NULL DEFAULT b'0',
`carepathphaseoid` INT(11) DEFAULT NULL,
`parentoid` INT(11) DEFAULT NULL,
`documentoid` INT(11) DEFAULT NULL,
`epdtemplateoid` INT(11) DEFAULT NULL,
`producttypeoid` INT(11) DEFAULT NULL,
`evaluateby` INT(11) DEFAULT NULL,
`pathlock` BIT(1) NOT NULL DEFAULT b'0',
`carepathgroupoid` INT(11) NOT NULL,
`activitygroupoid` INT(11) DEFAULT NULL,
`title` VARCHAR(45) DEFAULT NULL,
`carepathactionswitchtype` INT(11) DEFAULT NULL,
`modulesdomaincode` VARCHAR(10) DEFAULT NULL,
`startday` INT(11) NOT NULL DEFAULT '0',
`sourceoid` INT(11) DEFAULT NULL,
`templatefilename` VARCHAR(100) DEFAULT NULL,
`istask` BIT(1) NOT NULL DEFAULT b'0',
`typecontact` INT(11) DEFAULT NULL,
`carepathactionepdoid` INT(11) DEFAULT NULL,
`carepathactiontreatmentplanoid` INT(11) DEFAULT NULL,
`clientportalenabled` BIT(1) DEFAULT NULL,
`startafternumberofdaysepddatefield` INT(11) DEFAULT NULL,
`startafterdateepdfieldoid` INT(11) DEFAULT NULL,
`epdtemplatefieldoid` INT(11) DEFAULT NULL,
PRIMARY KEY (`oid`),
KEY `carepathactionfk1_idx` (`carepathoid`),
KEY `carepathactionfk2_idx` (`carepathphaseoid`),
KEY `carepathactionfk3_idx` (`documentoid`),
KEY `carepathactionfk4_idx` (`epdtemplateoid`),
KEY `carepathactionfk5_idx` (`producttypeoid`),
KEY `carepathactionfk6_idx` (`carepathgroupoid`),
KEY `carepathactionfk6_idx1` (`activitygroupoid`),
KEY `carepathactionfk7_idx` (`parentoid`),
KEY `carepathactionfk8_idx` (`usertaskoid`),
KEY `carepathactionfk10_idx` (`partyrolecategoryoid`),
KEY `carepathactionfk11_idx` (`carepathactionepdoid`),
KEY `carepathactionfk12_idx` (`carepathactiontreatmentplanoid`),
KEY `carepathactionfk13_idx` (`startafterdateepdfieldoid`),
KEY `carepathactionfk14_idx` (`epdtemplatefieldoid`),
CONSTRAINT `carepathactionfk14` FOREIGN KEY (`epdtemplatefieldoid`)
REFERENCES `epdtemplatefield` (`oid`) ON DELETE no action ON UPDATE no
action,
CONSTRAINT `carepathactionfk1` FOREIGN KEY (`carepathoid`) REFERENCES
`carepath` (`oid`) ON DELETE no action ON UPDATE no action,
CONSTRAINT `carepathactionfk10` FOREIGN KEY (`partyrolecategoryoid`)
REFERENCES `partyrolecategory` (`oid`) ON DELETE no action ON UPDATE no
action,
CONSTRAINT `carepathactionfk11` FOREIGN KEY (`carepathactionepdoid`)
REFERENCES `carepathaction` (`oid`) ON DELETE no action ON UPDATE no action
,
CONSTRAINT `carepathactionfk12` FOREIGN KEY (
`carepathactiontreatmentplanoid`) REFERENCES `carepathaction` (`oid`) ON
DELETE no action ON UPDATE no action,
CONSTRAINT `carepathactionfk13` FOREIGN KEY (`startafterdateepdfieldoid`)
REFERENCES `carepathaction` (`oid`) ON DELETE no action ON UPDATE no action
,
CONSTRAINT `carepathactionfk2` FOREIGN KEY (`carepathphaseoid`) REFERENCES
`carepathphase` (`oid`) ON DELETE no action ON UPDATE no action,
CONSTRAINT `carepathactionfk3` FOREIGN KEY (`documentoid`) REFERENCES
`document` (`oid`) ON DELETE no action ON UPDATE no action,
CONSTRAINT `carepathactionfk4` FOREIGN KEY (`epdtemplateoid`) REFERENCES
`epdtemplate` (`oid`) ON DELETE no action ON UPDATE no action,
CONSTRAINT `carepathactionfk5` FOREIGN KEY (`producttypeoid`) REFERENCES
`producttype` (`oid`) ON DELETE no action ON UPDATE no action,
CONSTRAINT `carepathactionfk6` FOREIGN KEY (`carepathgroupoid`) REFERENCES
`carepathgroup` (`oid`) ON DELETE no action ON UPDATE no action,
CONSTRAINT `carepathactionfk7` FOREIGN KEY (`parentoid`) REFERENCES
`carepathaction` (`oid`) ON DELETE no action ON UPDATE no action,
CONSTRAINT `carepathactionfk8` FOREIGN KEY (`usertaskoid`) REFERENCES
`tasktoschedule` (`oid`) ON DELETE no action ON UPDATE no action
)
CarePathGroup
CREATE TABLE `carepathgroup`
(
`oid` INT(11) NOT NULL,
`sequencenumber` INT(11) NOT NULL,
`title` VARCHAR(50) NOT NULL,
`carepathoid` INT(11) DEFAULT NULL,
`carepathphaseoid` INT(11) NOT NULL,
`sourceoid` INT(11) DEFAULT NULL,
PRIMARY KEY (`oid`),
KEY `carepathgroupfk1_idx` (`carepathoid`),
KEY `carepathgroupfk2_idx` (`carepathphaseoid`),
CONSTRAINT `carepathgroupfk2` FOREIGN KEY (`carepathphaseoid`) REFERENCES
`carepathphase` (`oid`) ON DELETE no action ON UPDATE no action
)
CarePathPhase
CREATE TABLE `carepathphase`
(
`oid` INT(11) NOT NULL,
`code` VARCHAR(6) NOT NULL,
`description` VARCHAR(45) NOT NULL,
`sequencenumber` INT(11) NOT NULL DEFAULT '0',
`carepathoid` INT(11) DEFAULT NULL,
`carepathphasetype` INT(11) NOT NULL DEFAULT '0',
`sourceoid` INT(11) DEFAULT NULL,
PRIMARY KEY (`oid`),
KEY `carepathphasefk1_idx` (`carepathoid`),
CONSTRAINT `carepathphasefk1` FOREIGN KEY (`carepathoid`) REFERENCES
`carepath` (`oid`) ON DELETE no action ON UPDATE no action
)
explain
1 SIMPLE f ALL PRIMARY 61925 Using where
1 SIMPLE g ref CarePathGroupFK2_idx CarePathGroupFK2_idx 4 amis.f.Oid 1
1 SIMPLE a1 ALL 166582 Using join buffer
1 SIMPLE a2 eq_ref PRIMARY,CarePathActionFK6_idx PRIMARY 4 amis.a1.SourceOid 1 Using where

There are two ALL join types in the explain, these are the ones you need to focus (for details see mysql documentation on explain output).
The create table statements show that:
You do not have index on the carepathphase.code field, which is used in the where criteria, so you should rectify that.
There is no index on carepathaction.sourceoid, which is used in the join, so you should create one there. You may try to create a combined index on oid, sourceoid fields (or the other way around) because mysql may be able to use the combined index to match the rows.
Run explain on the select (if you have mysql v5.6 or newer, then you can run it directly on the update) after adding the indexes and see, if the ALLs change. The 2nd all next to a2 seems to be the real critical stuff to me.

Related

mysql, results varying when I add a column to the select

Mysql version:
'innodb_version', '5.7.33'
'protocol_version', '10'
'slave_type_conversions', ''
'tls_version', 'TLSv1,TLSv1.1,TLSv1.2'
'version', '5.7.33-log'
'version_comment', 'Source distribution'
'version_compile_machine', 'x86_64'
'version_compile_os', 'Linux'
I have something very odd going on with a production mysql database that I can not suss out & I may struggle to explain. When I copy the database over to somewhere else everything is fine.
There are 1.5 million rows in method_profile & so far this is the only row I know to have this issue.
The problem is displayed in two ways. 1) why do I get back an invalid id of '-2147476736' & why do I get no rows back when I ad deleted_timestamp to the SQL.
This first select returns a row as I expect:
select mp.id, mp.screening_profile_id, mp.deleted, mp.deleted_timestamp
from method_profile mp
where mp.id = 481031;
So then using the screening_profile_id value I run the following SQL:
select mp.id, mp.screening_profile_id, mp.deleted from method_profile mp
where mp.screening_profile_id = 420062 ;
That id does not exist as shown by:
select mp.id from method_profile mp where mp.id = -2147476736;
If I change the second select to add another column 'mp.deleted_timestamp' I then get no row back at all:
select mp.id, mp.screening_profile_id, mp.deleted, mp.deleted_timestamp from method_profile mp
where mp.screening_profile_id = 420062 ;
The CREATE statement for the table is as follows:
CREATE TABLE `method_profile` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '5.1',
`primary_method_id` int(11) DEFAULT NULL,
`secondary_method_id` int(11) DEFAULT NULL,
`instrument_id` int(11) DEFAULT NULL,
`kit_code_id` int(11) DEFAULT NULL COMMENT '5.1 - allow NULL as option see http://youtrack/issue/PTPORTAL2-100',
`temperature_id` int(11) DEFAULT NULL,
`name` varchar(180) DEFAULT NULL,
`slope` decimal(10,3) DEFAULT NULL COMMENT '7.7',
`intercept` decimal(10,3) DEFAULT NULL COMMENT '7.7',
`deleted` bit(1) NOT NULL DEFAULT b'0',
`screening_profile_id` int(11) NOT NULL,
`round_id_valid_from` int(11) DEFAULT NULL,
`round_id_valid_to` int(11) DEFAULT NULL,
`measurement_unit_id` int(11) DEFAULT NULL,
`instrument_ref` varchar(20) DEFAULT NULL,
`generated_primary_method_id` int(11) GENERATED ALWAYS AS (ifnull(`primary_method_id`,0)) VIRTUAL NOT NULL,
`generated_secondary_method_id` int(11) GENERATED ALWAYS AS (ifnull(`secondary_method_id`,0)) VIRTUAL NOT NULL,
`generated_instrument_id` int(11) GENERATED ALWAYS AS (ifnull(`instrument_id`,0)) VIRTUAL NOT NULL,
`generated_instrument_ref` varchar(20) GENERATED ALWAYS AS (ifnull(`instrument_ref`,'')) VIRTUAL NOT NULL,
`generated_round_id_valid_from` int(11) GENERATED ALWAYS AS (ifnull(`round_id_valid_from`,0)) VIRTUAL NOT NULL,
`generated_round_id_valid_to` int(11) GENERATED ALWAYS AS (ifnull(`round_id_valid_to`,0)) VIRTUAL NOT NULL,
`generated_kit_code_id` int(11) GENERATED ALWAYS AS (ifnull(`kit_code_id`,0)) VIRTUAL NOT NULL,
`generated_temperature_id` int(11) GENERATED ALWAYS AS (ifnull(`temperature_id`,0)) VIRTUAL NOT NULL,
`generated_name` varchar(180) GENERATED ALWAYS AS (ifnull(`name`,'')) VIRTUAL NOT NULL,
`generated_slope` decimal(10,3) GENERATED ALWAYS AS (ifnull(`slope`,0.0)) VIRTUAL NOT NULL,
`generated_intercept` decimal(10,3) GENERATED ALWAYS AS (ifnull(`intercept`,0.0)) VIRTUAL NOT NULL,
`generated_measurement_unit_id` int(11) GENERATED ALWAYS AS (ifnull(`measurement_unit_id`,0)) VIRTUAL NOT NULL,
`inserted_at` datetime DEFAULT CURRENT_TIMESTAMP,
`last_updated` datetime DEFAULT CURRENT_TIMESTAMP,
`deleted_timestamp` timestamp NULL DEFAULT NULL,
`generated_deleted_timestamp` timestamp GENERATED ALWAYS AS (ifnull(`deleted_timestamp`,'0000-00-00 00:00:00')) VIRTUAL NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `method_profile_instrument_ref_uniq_idx` (`screening_profile_id`,`generated_primary_method_id`,`generated_secondary_method_id`,`generated_instrument_id`,`generated_instrument_ref`,`generated_round_id_valid_from`,`generated_round_id_valid_to`,`generated_kit_code_id`,`generated_temperature_id`,`generated_name`,`generated_slope`,`generated_intercept`,`generated_measurement_unit_id`,`deleted`,`generated_deleted_timestamp`),
KEY `fk_screening_profile_Kit_code1_idx` (`kit_code_id`),
KEY `fk_screening_profile_temperature1_idx` (`temperature_id`),
KEY `fk_screening_profile_method1_idx` (`primary_method_id`),
KEY `fk_screening_profile_method2_idx` (`secondary_method_id`),
KEY `fk_screening_profile_instrument1_idx` (`instrument_id`),
KEY `fk_method_profile_screening_profile` (`screening_profile_id`),
KEY `fk_method_profile_round_id_valid_from` (`round_id_valid_from`),
KEY `fk_method_profile_round_id_valid_to` (`round_id_valid_to`),
KEY `fk_method_profile_measurement_unit_id` (`measurement_unit_id`),
CONSTRAINT `fk_method_profile_instrument` FOREIGN KEY (`instrument_id`) REFERENCES `instrument` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_method_profile_kit_code` FOREIGN KEY (`kit_code_id`) REFERENCES `kit_code` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_method_profile_measurement_unit_id` FOREIGN KEY (`measurement_unit_id`) REFERENCES `measurement_units` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_method_profile_primary_method` FOREIGN KEY (`primary_method_id`) REFERENCES `method` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_method_profile_round_id_valid_from` FOREIGN KEY (`round_id_valid_from`) REFERENCES `round` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_method_profile_round_id_valid_to` FOREIGN KEY (`round_id_valid_to`) REFERENCES `round` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_method_profile_screening_profile` FOREIGN KEY (`screening_profile_id`) REFERENCES `screening_profile` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_method_profile_secondary_method` FOREIGN KEY (`secondary_method_id`) REFERENCES `method` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_method_profile_temperature` FOREIGN KEY (`temperature_id`) REFERENCES `temperature` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1614629 DEFAULT CHARSET=utf8mb4;

mysql ignore index for order by on join

CREATE TABLE `call_session` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`contact_id` bigint(20) unsigned NOT NULL,
`campaign_id` bigint(20) unsigned DEFAULT NULL,
`user_id` bigint(20) unsigned DEFAULT NULL,
`start_time` datetime DEFAULT NULL,
`end_time` datetime DEFAULT NULL,
`type` varchar(16) DEFAULT NULL,
`status` varchar(16) DEFAULT NULL,
`continue_reason_id` bigint(20) unsigned DEFAULT NULL,
`continue_by` bigint(20) unsigned DEFAULT NULL,
`end_reason_id` bigint(20) unsigned DEFAULT NULL,
`comment` varchar(255) DEFAULT '',
`call_count` int(11) NOT NULL DEFAULT '0',
`answered_call_count` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `ix_call_session_contact_id` (`contact_id`),
KEY `ix_call_session_user_id` (`user_id`),
KEY `ix_call_session_campaign_id` (`campaign_id`),
KEY `call_session_continue_by_foreign` (`continue_by`),
KEY `call_session_end_reason_id_foreign` (`end_reason_id`),
KEY `ix_call_session_end_time` (`end_time`),
KEY `ix_call_session_start_time` (`start_time`),
KEY `ix_call_session_continue_reason_id` (`continue_reason_id`),
CONSTRAINT `call_session_campaign_id_foreign` FOREIGN KEY (`campaign_id`) REFERENCES `campaign` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `call_session_continue_by_foreign` FOREIGN KEY (`continue_by`) REFERENCES `user` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `call_session_continue_reason_id_foreign` FOREIGN KEY (`continue_reason_id`) REFERENCES `continue_reason` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `call_session_end_reason_id_foreign` FOREIGN KEY (`end_reason_id`) REFERENCES `end_reason` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `call_session_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
)
CREATE TABLE `continue_reason` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`project_id` bigint(20) unsigned DEFAULT NULL,
`sort` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `ix_continue_reason_project_id` (`project_id`),
CONSTRAINT `continue_reason_project_id_foreign` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
)
The call_session table contain more than 500,000 rows.
The continue_reason table contain only one row.
When I join the continue_reason table for the name column, mysql ignore the start_date index so the query takes between 1.8 to 3 seconds.
I can't figure out why.
The problematic query is:
SELECT `call_session`.`id`,
`continue_reason`.`name`
FROM `call_session`
LEFT JOIN `continue_reason` ON `continue_reason`.`id` = `call_session`.`continue_reason_id`
ORDER BY `call_session`.`start_time` DESC LIMIT 1;
Explain result:
Same query without join works great:
SELECT `call_session`.`id`,
(SELECT `name` FROM `continue_reason` WHERE id = `call_session`.`continue_reason_id`) AS `continue_reason.name`
FROM `call_session`
ORDER BY `call_session`.`start_time` DESC LIMIT 1;
Explain results:
I found many similar questions but I don't have any DISTINCT, no GROUP BY, and there is a very clear benefit for using the index.
Any thoughts?
Thanks in advance
P.S. Force index didn't help.
Here is the Optimizer report

Foreign key constraint fails with Insert Into Select in MySQL

I'm quite new to SQL, and I'm trying to upload data to my tables. For this I have special tables where I upload the data from a CSV file, and then, from this table, I am trying to copy the data to the final table.
But now I have a problem with an intermediate table where I have uploaded my data. The table is:
CREATE TABLE `_work_has_person` (
`work_id` int(11) NOT NULL,
`person_id` int(11) NOT NULL,
`primary_contribution_id` int(11) DEFAULT NULL,
PRIMARY KEY (`work_id`,`person_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I want to copy the data in
CREATE TABLE `work_has_person` (
`work_id` int(11) NOT NULL,
`person_id` int(11) NOT NULL,
`primary_contribution_id` int(11) NOT NULL,
PRIMARY KEY (`work_id`,`person_id`),
KEY `fk_work_has_person_person1_idx` (`person_id`),
KEY `fk_work_has_person_work1_idx` (`work_id`),
KEY `fk_work_has_person_primary_contribution1_idx` (`primary_contribution_id`),
CONSTRAINT `fk_work_has_person_person1` FOREIGN KEY (`person_id`) REFERENCES `person` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_work_has_person_primary_contribution1` FOREIGN KEY (`primary_contribution_id`) REFERENCES `primary_contribution` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_work_has_person_work1` FOREIGN KEY (`work_id`) REFERENCES `work` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Which is an intermediate table between:
CREATE TABLE `work` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title_work` varchar(250) DEFAULT NULL,
`subtitle_work` varchar(250) DEFAULT NULL,
`date_work` varchar(45) DEFAULT NULL,
`unix_date_work` varchar(100) DEFAULT NULL,
`sinopsis` text,
`ref_bne` varchar(100) DEFAULT NULL,
`ref_alt` longtext,
`language_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_work_language1_idx` (`language_id`),
KEY `title_work` (`title_work`),
CONSTRAINT `fk_work_language1` FOREIGN KEY (`language_id`) REFERENCES `language` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=24610 DEFAULT CHARSET=utf8;
and
CREATE TABLE `person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`img_person` varchar(250) DEFAULT NULL,
`born_date` varchar(45) DEFAULT NULL,
`unix_born_date` varchar(100) DEFAULT NULL,
`city_born_date` varchar(100) DEFAULT NULL,
`country_born_date` varchar(100) DEFAULT NULL,
`death_date` varchar(45) DEFAULT NULL,
`unix_death_date` varchar(100) DEFAULT NULL,
`city_death_date` varchar(100) DEFAULT NULL,
`country_death_date` varchar(45) DEFAULT NULL,
`biography` longtext,
`ref_bne` varchar(100) DEFAULT NULL,
`ref_alt` longtext,
PRIMARY KEY (`id`),
UNIQUE KEY `name_UNIQUE` (`name`),
KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=9159 DEFAULT CHARSET=utf8;
But everytime I try to run
INSERT INTO work_has_person (work_id, person_id, primary_contribution_id)
SELECT work_id, person_id, primary_contribution_id
FROM _work_has_person;
It says
Cannot add or update a child row: a foreign key constraint fails (`cdu93hfg93r`.
`work_has_person`, CONSTRAINT `fk_work_has_person_person1` FOREIGN KEY (`person_id`)
REFERENCES `person` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
I am pretty sure that the tables has the neccesary data, but, ¿is there a way to know which data fails? I have seen Mysql error 1452 - Cannot add or update a child row: a foreign key constraint fails: but don't understand exactly how to use it here.
A.
It is relatively easy to find out what data is causing the conflict: get all person_ids from _work_has_person that are not in the persons table. You can achieve this via an outer join and filtering for person.id is null in the where clause.
select * from `_work_has_person` whp
left join person p on whp.person_id=p.id
where p.id is null
You can actually remove such data from the results being inserted by including the reverse criterion into the select part of your insert query (an inner join):
INSERT INTO work_has_person (work_id, person_id, primary_contribution_id)
SELECT whp.work_id, whp.person_id, whp.primary_contribution_id
FROM _work_has_person whp
INNER join person p on whp.person_id=p.id

not able to apply foreign key constraint in mysql

I can run the below query and there are no nulls in the user_id column in the result -
select c.*,r.user_id from chat_group_users c left join roleuser r
on c.user_id = r.user_id;
But I cannot apply the foreign key constraint and mysql just says
Error Code: 1215. Cannot add foreign key constraint
The command i wrote -
ALTER TABLE chat_group_users
ADD CONSTRAINT fk_roleuser FOREIGN KEY (user_id) REFERENCES roleuser (user_id)
ON DELETE cascade ON UPDATE cascade;
The table structures -
CREATE TABLE `roleuser` (
`User_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`UserNM` varchar(50) NOT NULL,
`UserPS` varchar(150) NOT NULL,
`r_username` varchar(50) DEFAULT NULL,
`UGroup` varchar(5) NOT NULL DEFAULT 'Usar',
`FirstName` varchar(45) NOT NULL,
`LastName` varchar(45) NOT NULL,
PRIMARY KEY (`User_ID`),
UNIQUE KEY `Index_2` (`UserNM`),
) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=latin1;
CREATE TABLE `chat_group_users` (
`auto_id` int(11) NOT NULL AUTO_INCREMENT,
`group_id` int(11) DEFAULT NULL,
`user_id` int(10) DEFAULT NULL,
`is_admin` varchar(5) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`auto_id`),
UNIQUE KEY `unique_user_group` (`user_id`,`group_id`),
KEY `fc_group_id` (`group_id`),
CONSTRAINT `fc_group_id` FOREIGN KEY (`group_id`)
REFERENCES `chat_group`(`auto_id`)
ON DELETE CASCADE ON UPDATE CASCADE
)ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
missed the unsigned on the chat_group_users -
`User_ID` int(10) unsigned NOT NULL AUTO_INCREMENT, ...

mysql composite foreign key referencing more than 2 attributes

Hi I have a table with 3 attributes as primary key
Products:
PRIMARY KEY (product_name,category,product_type).
Now i am referencing this composite primary key in another table
order_details:
foreign key(product_name,product_type,category) references products(product_name,product_type,category)
however I am getting an error in the console saying missing parenthesis and I am not able to add the foreign key. But if i add only 2 column names in the reference(example : "foreign key(product_name,product_type,category) references products(product_name,product_type)
") the query is not giving an error.
Please help me to resolve this issue. Please find my code below
CREATE TABLE `products` (
`product_name` varchar(45) NOT NULL,
`product_type` varchar(45) NOT NULL,
`category` varchar(45) NOT NULL,
`product_desc` varchar(150) DEFAULT NULL,
`unit_price` int(11) NOT NULL,
`supplier_id` int(11) NOT NULL,
`units_in_stock` int(11) NOT NULL,
PRIMARY KEY (`product_name`,`category`,`product_type`),
INDEX (product_name,category,product_type),
CONSTRAINT `supplier_prod_table_fkey` FOREIGN KEY (`supplier_id`) REFERENCES
`supplier` (`supplier_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=INNODB;
CREATE TABLE `order_details` (
`order_id` int(11) NOT NULL AUTO_INCREMENT,
`product_name` varchar(45) NOT NULL,
`product_type` varchar(45) NOT NULL,
`category` varchar(45) NOT NULL,
`quantity` int(11) DEFAULT NULL,
CONSTRAINT `orderid_fkey` FOREIGN KEY (`order_id`) REFERENCES `orders`
(`order_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
PRIMARY KEY (`order_id`,`product_name`,`product_type`,`category`),
INDEX (product_name,product_type,category),
foreign key(product_name,product_type,category) references products(product_name,product_type,category)
);
Fields in REFERENCES and in correspondent indices must go in the same order in both tables, i.e. (product_name, category, product_type).
CREATE TABLE `order_details` (
`order_id` int(11) NOT NULL AUTO_INCREMENT,
`product_name` varchar(45) NOT NULL,
`product_type` varchar(45) NOT NULL,
`category` varchar(45) NOT NULL,
`quantity` int(11) DEFAULT NULL,
CONSTRAINT `orderid_fkey` FOREIGN KEY (`order_id`) REFERENCES `orders`
(`order_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
PRIMARY KEY (`order_id`,`product_name`,`product_type`,`category`),
INDEX (product_name,category,product_type),
FOREIGN KEY(product_name,category,product_type) REFERENCES products(product_name,category,product_type)
);