I have two huge tables from which i have select huge amount of data.
Tables store Purchase Order Details and product information.
PURCHASE_ORDER_DETAILS.
CREATE TABLE `PURCHASE_ORDER_DETAILS` (
`PURCHASE_ORDER_NUMBER_PF` INT(20) NOT NULL,
`PRODUCT_CODE_PF` VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`ORDER_QUANTITY` INT(8) DEFAULT NULL,
`UNIT_PRICE` DECIMAL(12,2) DEFAULT NULL,
`ORDER_FULLFILLMENT_DUE_DATE` DATETIME DEFAULT NULL,
`DELIVERY_ADDRESS` VARCHAR(64) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
`DELIVERY_CITY` VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
`DELIVERY_ZIP` BIGINT(10) DEFAULT NULL,
`other columns`
PRIMARY KEY (`PURCHASE_ORDER_NUMBER_PF`,`PRODUCT_CODE_PF`),
KEY `RMAPWBTX_PUCH_ORDE_DLST_INDX` (`DELIVERY_STATE_ID_FK`),
KEY `RMAPWBTX_PUCH_ORDE_DLTY_INDX` (`DELIVERY_TYPE_FK`),
KEY `RMAPWBTX_PUCH_ORDE_TACO_INDX` (`TAX_CODE_FK`),
KEY `RMAPWBMS_PUOR_DETL_PDCO_FK` (`PRODUCT_CODE_PF`),
KEY `RMAPWBTX_PUOR_DETL_TACO_FK` (`TAX_CODE_FK`),
KEY `CREATED_DATE_INDX` (`CREATED_DATE`),
KEY `MODIFIED_DATE_INDX` (`MODIFIED_DATE`),
CONSTRAINT `RMAPWBMS_PUOR_DETL_PDCO_FK` FOREIGN KEY (`PRODUCT_CODE_PF`)
REFERENCES `PRODUCT` (`PRODUCT_CODE_PK`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `RMAPWBMS_PUOR_DETL_PONU_FK` FOREIGN KEY
(`PURCHASE_ORDER_NUMBER_PF`) REFERENCES `PURCHASE_ORDER`
(`PURCHASE_ORDER_NUMBER_PK`),
CONSTRAINT `RMAPWBTX_PO_DETL_DSID_FK` FOREIGN KEY
(`DELIVERY_STATE_ID_FK`) REFERENCES `STATE` (`STATE_ID_PK`),
CONSTRAINT `RMAPWBTX_PUOR_DETL_TACO_FK` FOREIGN KEY (`TAX_CODE_FK`)
REFERENCES `TAX` (`TAX_CODE_PK`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=INNODB DEFAULT CHARSET=latin1;
PRODUCT
CREATE TABLE `PRODUCT` (
`PRODUCT_CODE_PK` VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`PRODUCT_DESC` VARCHAR(256) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
`FEE_BILL_CODE` VARCHAR(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
`other columns`
PRIMARY KEY (`PRODUCT_CODE_PK`),
KEY `CREATED_DATE_INDX` (`CREATED_DATE`),
KEY `MODIFIED_DATE_INDX` (`MODIFIED_DATE`),
KEY `PRODUCT_EXCO_FK` (`EXPENSE_CODE_ID_FK`),
KEY `FK_PRODUCT_ENTITY_TYPE` (`ENTITY_TYPE_CODE_FK`),
CONSTRAINT `FK_PRODUCT_ENTITY_TYPE` FOREIGN KEY (`ENTITY_TYPE_CODE_FK`) REFERENCES `ENTITY_TYPE` (`ENTITY_TYPE_CODE_PK`)
) ENGINE=INNODB DEFAULT CHARSET=latin1
Below query is taking ~10min to get ~1M records.
EXPLAIN SELECT * FROM
PURCHASE_ORDER_DETAILS POD
JOIN PRODUCT PRD ON POD.PRODUCT_CODE_PF=PRD.PRODUCT_CODE_PK;
+----+-------------+-------+------+----------------------------+-----------------
-----------+---------+-----------------------------------------------+-------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+----------------------------+----------------------------+---------+-----------------------------------------------+-------+-------+
| 1 | SIMPLE | PRD | ALL | PRIMARY | NULL | NULL | NULL | 14283 | NULL |
| 1 | SIMPLE | POD | ref | RMAPWBMS_PUOR_DETL_PDCO_FK | RMAPWBMS_PUOR_DETL_PDCO_FK | 34 | REALREMIT_PROD_ALTISOURCE.PRD.PRODUCT_CODE_PK | 40 | NULL |
+----+-------------+-------+------+----------------------------+----------------------------+---------+-----------------------------------------------+-------+---
Edit1:
Above query was an example, below is the actual query where i am trying to fetch 1M records (main table POD has 22M records).
SELECT `some columns`
FROM `REALREMIT_PPIPFC_MIG`.MIGR_ORDER_DENORM MPO
INNER JOIN PURCHASE_ORDER_DETAILS POD
ON MPO.PURCHASE_ORDER_NUMBER_PK=POD.PURCHASE_ORDER_NUMBER_PF
INNER JOIN PRODUCT PRD
ON POD.PRODUCT_CODE_PF=PRD.PRODUCT_CODE_PK
INNER JOIN EXPENSE_CODE EXP
ON PRD.EXPENSE_CODE_ID_FK=EXP.EXPENSE_CODE_ID_PK
WHERE MPO.BATCH_ID=1;
Explain Output for the above query
+----+-------------+-------+--------+-------------------------------------+----------------------------+---------+--------------------------------------------------------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+-------------------------------------+----------------------------+---------+--------------------------------------------------------+-------+-------------+
| 1 | SIMPLE | PRD | ALL | PRIMARY,PRODUCT_EXCO_FK | NULL | NULL | NULL | 14283 | NULL |
| 1 | SIMPLE | EXP | eq_ref | PRIMARY | PRIMARY | 4 | REALREMIT_PROD_ALTISOURCE.PRD.EXPENSE_CODE_ID_FK | 1 | NULL |
| 1 | SIMPLE | POD | ref | PRIMARY,RMAPWBMS_PUOR_DETL_PDCO_FK | RMAPWBMS_PUOR_DETL_PDCO_FK | 34 | REALREMIT_PROD_ALTISOURCE.PRD.PRODUCT_CODE_PK | 40 | NULL |
| 1 | SIMPLE | MPO | ref | MIGR_PO_NBR_INDX,MIGR_BATCH_ID_INDX | MIGR_PO_NBR_INDX | 4 | REALREMIT_PROD_ALTISOURCE.POD.PURCHASE_ORDER_NUMBER_PF | 1 | Using where |
+----+-------------+-------+--------+-------------------------------------+----------------------------+---------+--------------------------------------------------------+-------+-------------+
4 rows in set (0.20 sec)
Both database have same charset
Columns used in join have the same collate
Both tables have same charset
I have created new table in which primary key is concatenated column - PURHCASE_ORDER_NUMBER_PF and PRODUCT_CODE_PF and then i have added a new index on PRODUCT_CODE_PF
Will index be used in this case and/or is this the best way to make use of index in join.
Thanks
These may help:
MPO: INDEX(BATCH_ID, PURCHASE_ORDER_NUMBER_PK) -- in this order
EXP: INDEX(EXPENSE_CODE_ID_PK) -- unless it is the PRIMARY KEY
But, without knowing what is in "some columns", I can't predict how much they will help. And it would help to have SHOW CREATE TABLE for MPO and EXP.
How much RAM do you have? What is the value of innodb_buffer_pool_size? I ask because you may be thrashing.
Related
So i'm trying to create a library database and was wondering if something i'm trying to achieve is possible through the use of triggers or similar.
I have this table called "category" which contains the different categories that you can borrow, like books or dvds.
And depending on what product category you lend from, you have different times allowed, like books you can borrow for 3 weeks but dvds are only allowed 3 days.
+--------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | | NULL | |
| time_allowed | time | NO | | NULL | |
| days_allowed | varchar(400) | NO | | NULL | |
+--------------+---------------+------+-----+---------+----------------+
And then i have the table "Borrowed" which looks like this
+---------------+-------------------+-------+-----+----------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------------+-------+-----+----------------------+-----------------------------+
| id | int(11) | NO | PRI | None | auto_increment |
| item_id | int(11) | NO | | NULL | |
| date_borrowed | timestamp | NO | | CURRENT_TIMESTAMP | |
| return_by | datetime | NO | | None | |
| returned | enum('No','Yes') | NO | | No | |
| borrower_id | int(11) | NO | | None | |
| time_returned | timestamp | Yes | | CURRENT_TIMESTAMP | ON UPDATE CURRENT_TIMESTAMP |
+---------------+-------------------+-------+-----+----------------------+-----------------------------+
Now what i want to do is take the "date_borrowed" from "Borrowed" + "time_allowed" + "days_allowed" from the "Category" table to create the datetime value for "return_by" in the "Borrowed" table.
So if the "date_borrowed" is "2016-01-01 12:00:00" and a dvd is borrowed then the "return_by" should be "2016-01-04 12:00:00".
Is this possible to do through Triggers ?
Any and all feedback is much appreciated.
UPDATE:
CREATE TABLE `borrowed` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item_id` int(11) DEFAULT NULL,
`date_borrowed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`return_by` datetime NOT NULL,
`returned` enum('No','Yes') CHARACTER SET utf8 NOT NULL DEFAULT 'No',
`borrower_id` int(11) NOT NULL,
`time_returned` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `borrower_id_idx` (`borrower_id`),
KEY `item_id_idx` (`item_id`),
CONSTRAINT `borrowed_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `items` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `borrower_id` FOREIGN KEY (`borrower_id`) REFERENCES `borrower` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
CREATE TABLE `category` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8 NOT NULL,
`time_allowed` time NOT NULL,
`days_allowed` varchar(400) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
CREATE TABLE `items` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item_name` varchar(150) CHARACTER SET utf8 NOT NULL,
`item_uniqueid` varchar(100) CHARACTER SET utf8 NOT NULL COMMENT 'This can be a Serial Number or a ISBN number. But has to be unique for that item',
`item_status` enum('Ok','Damaged','Broken') CHARACTER SET utf8 NOT NULL,
`item_comment` longtext CHARACTER SET utf8,
`item_retired` enum('No','Yes') CHARACTER SET utf8 NOT NULL DEFAULT 'No',
`item_dop` date NOT NULL COMMENT 'item_dop = Item Date Of Purchaes',
`item_category` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `id_category_idx` (`item_category`),
CONSTRAINT `id_category` FOREIGN KEY (`item_category`) REFERENCES `category` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
First you need to allow NULLs for the return_by column:
ALTER TABLE `borrowed`
ALTER `return_by` DROP DEFAULT;
ALTER TABLE `borrowed`
CHANGE COLUMN `return_by` `return_by` DATETIME NULL AFTER `date_borrowed`;
Then create a BEFORE INSERT trigger for the borrowed table:
DELIMITER //
CREATE TRIGGER `borrowed_before_insert` BEFORE INSERT ON `borrowed` FOR EACH ROW BEGIN
set new.return_by = (
select new.date_borrowed
+ interval c.days_allowed day
+ interval time_to_sec(c.time_allowed) second
from items i
join category c on c.id = i.item_category
where i.id = new.item_id
);
END//
DELIMITER ;
SQLFiddle-Demo
If you ever update the date_borrowed column, you will also need an UPDATE trigger to ajust the return_by value.
Assuming that you time_allowed is in HOUR, your days_allowed is in number of days (an not a varchar for string) and the two tables are related by a column relation_key and key you could suing a select llike this
select TIMESTAMPADD(HOUR, c.time_allowed,
TIMESTAMPADD( DAY ,c.days_allowed,b.date_borrowed) )
from Borrowed as b
inner join catogory on b.relation_key = c.key
mysql> EXPLAIN SELECT * FROM
(`phppos_modules`)
JOIN `phppos_permissions` ON `phppos_permissions`.`module_id`=`phppos_modules`.`module_id`
WHERE `phppos_permissions`.`person_id` = '1'
ORDER BY `sort` asc;
+----+-------------+--------------------+--------+-------------------+---------+---------+------------------------------------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------------+--------+-------------------+---------+---------+------------------------------------+------+----------------+
| 1 | SIMPLE | phppos_modules | ALL | PRIMARY | NULL | NULL | NULL | 11 | Using filesort |
| 1 | SIMPLE | phppos_permissions | eq_ref | PRIMARY,person_id | PRIMARY | 306 | pos.phppos_modules.module_id,const | 1 | Using index |
+----+-------------+--------------------+--------+-------------------+---------+---------+------------------------------------+------+----------------+
2 rows in set (0.00 sec)
mysql> show create table phppos_modules;
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| phppos_modules | CREATE TABLE `phppos_modules` (
`name_lang_key` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`desc_lang_key` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`sort` int(10) NOT NULL,
`icon` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`module_id` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`module_id`),
UNIQUE KEY `desc_lang_key` (`desc_lang_key`),
UNIQUE KEY `name_lang_key` (`name_lang_key`),
KEY `sort` (`sort`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
mysql> show create table phppos_permissions;
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| phppos_permissions | CREATE TABLE `phppos_permissions` (
`module_id` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`person_id` int(10) NOT NULL,
PRIMARY KEY (`module_id`,`person_id`),
KEY `person_id` (`person_id`),
CONSTRAINT `phppos_permissions_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `phppos_employees` (`person_id`),
CONSTRAINT `phppos_permissions_ibfk_2` FOREIGN KEY (`module_id`) REFERENCES `phppos_modules` (`module_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
Likely you are being affected by this condition from the documentation:
The key used to fetch the rows is not the same as the one used in the
ORDER BY:
SELECT * FROM t1 WHERE key2=constant ORDER BY key1;
Try the following:
ALTER TABLE `phppos_modules`
ADD INDEX `all_w_sort_first` (`sort`,`module_id`,`name_lang_key`,`desc_lang_key`,`icon`);
Edit: Not sure why this is marked as a duplicate. The error I am getting is different
I am trying to remove a primary key definition but am receiving an error for some reason.
mysql> ALTER TABLE `aux_sponsors` DROP PRIMARY KEY;
ERROR 1091 (42000): Can't DROP 'PRIMARY'; check that column/key exists
mysql> desc aux_sponsors;
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| unit | varchar(8) | NO | | MF | |
| code | varchar(32) | NO | PRI | NULL | |
| userid | varchar(32) | NO | | | |
| fullName | varchar(64) | NO | | | |
| department | varchar(255) | NO | | | |
| description | varchar(255) | NO | | NULL | |
+-------------+--------------+------+-----+---------+-------+
6 rows in set (0.01 sec)
Am I doing something wrong here? I simply want no more primary key in this table.
mysql> SHOW CREATE TABLE aux_sponsors;
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| aux_sponsors | CREATE TABLE `aux_sponsors` (
`unit` varchar(8) NOT NULL DEFAULT 'MF',
`code` varchar(32) NOT NULL,
`userid` varchar(32) NOT NULL DEFAULT '',
`fullName` varchar(64) NOT NULL DEFAULT '',
`department` varchar(255) NOT NULL DEFAULT '',
`description` varchar(255) NOT NULL,
UNIQUE KEY `code` (`code`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
You don't have a PRIMARY KEY; you have a UNIQUE key. So, you can't do this:
ALTER TABLE `aux_sponsors` DROP PRIMARY KEY
Instead, just do
ALTER TABLE `aux_sponsors` DROP KEY `code`
DESC (a/k/a DESCRIBE) is not a true MySQL feature; according to the docs, "The DESCRIBE statement is provided for compatibility with Oracle."
More from the documentation:
A UNIQUE index may be displayed as PRI if it cannot contain NULL values and there is no PRIMARY KEY in the table. A UNIQUE index may display as MUL if several columns form a composite UNIQUE index; although the combination of the columns is unique, each column can still hold multiple occurrences of a given value.
In your case, the column code is NOT NULL and is the only column in a UNIQUE key, so DESC is showing it as PRI. Because of this type of problem, it's better to use SHOW INDEX to find out the types of keys on a table.
I have found that MySQL (Win 7 64, 5.6.14) does not use index properly if I specify table output for IN statement. USER table contains 900k records.
If I use IN (_SOME_TABLE_OUTPUT_) syntax - I get fullscan for all 900k users. Query runs forever.
If I use IN ('CONCRETE','VALUES') syntax - I get a correct index usage.
How can I make MySQL finally USE the index?
1st case:
explain SELECT gu.id FROM USER gu WHERE gu.uuid in
(select '11b6a540-0dc5-44e0-877d-b3b83f331231' union
select '11b6a540-0dc5-44e0-877d-b3b83f331232');
+----+--------------------+------------+-------+---------------+------+---------+------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+-------+---------------+------+---------+------+--------+--------------------------+
| 1 | PRIMARY | gu | index | NULL | uuid | 257 | NULL | 829930 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
| 3 | DEPENDENT UNION | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
| NULL | UNION RESULT | <union2,3> | ALL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------------+------------+-------+---------------+------+---------+------+--------+--------------------------+
2nd case:
explain SELECT gu.id FROM USER gu WHERE gu.uuid in
('11b6a540-0dc5-44e0-877d-b3b83f331231');
+----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+
| 1 | SIMPLE | gu | ref | uuid | uuid | 257 | const | 1 | Using where; Using index |
+----+-------------+-------+------+---------------+------+---------+-------+------+--------------------------+
Table structure:
CREATE TABLE `USER` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`version` bigint(20) NOT NULL,
`email` varchar(255) DEFAULT NULL,
`uuid` varchar(255) NOT NULL,
`partner_id` bigint(20) NOT NULL,
`password` varchar(255) DEFAULT NULL,
`date_created` datetime DEFAULT NULL,
`last_updated` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique-email` (`partner_id`,`email`),
KEY `uuid` (`uuid`),
CONSTRAINT `fk_USER_partner` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`) ON DELETE CASCADE,
CONSTRAINT `FKB2D9FEBE725C505E` FOREIGN KEY (`partner_id`) REFERENCES `partner` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3315452 DEFAULT CHARSET=latin1
FORCE INDEX and USE INDEX statements don't change anything.
Demonstration SQLfiddle: http://sqlfiddle.com/#!2/c607e1/2
In fact I faced such problem before and it happened that I had one table that had a single column set as UTF-8 and the other tables where latin1. It did not matter what I did, MySQL insisted on using no indexes. The problem is quite well described on this blog post Slow queries in MySQL due to collation problems. Once you manage to fix the character set, I believe any of the queries will work.
An inner join on your virtual table might give you better performance. Try something along these lines.
SELECT gu.id
FROM USER gu
INNER JOIN (
select '11b6a540-0dc5-44e0-877d-b3b83f331231' uuid
union all
select '11b6a540-0dc5-44e0-877d-b3b83f331232') ids
on gu.uuid = ids.uuid;
I'm trying to add a foreign key constraint to the table ag by using:
alter table ag
add foreign key fk_ag_protein1 (protein_PID) references protein (PID);
But I get the following error message:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails
(`mux_new`.`#sql-884_3`, CONSTRAINT `#sql-884_3_ibfk_1` FOREIGN KEY (`protein_PID`)
REFERENCES `protein` (`PID`))"
To get more details I checked output from:
SHOW ENGINE INNODB STATUS\G
Which was:
LATEST FOREIGN KEY ERROR
------------------------
TRANSACTION 193923, ACTIVE 0 sec inserting, thread declared inside InnoDB 4999
mysql tables in use 2, locked 2
5 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
MySQL thread id 3, OS thread handle 0x1714, query id 143 localhost ::1 root copy
to tmp table
alter table ag
add foreign key fk_ag_protein1 (protein_PID) references protein (PID)
Foreign key constraint fails for table `mux_new`.`#sql-884_3`:
,
CONSTRAINT `#sql-884_3_ibfk_1` FOREIGN KEY (`protein_PID`) REFERENCES `protein
` (`PID`)
Trying to add in child table, in index `fk_ag_protein1` tuple:
DATA TUPLE: 2 fields;
0: len 4; hex 80000000; asc ;;
1: len 3; hex 002711; asc ' ;;
But in parent table `mux_new`.`protein`, in index `PRIMARY`,
the closest match we can find is record:
PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 696e66696d756d00; asc infimum ;;
But I do not understand this at all. The table ag currently contains some data but protein does not.
Any ideas of what my problem could be or things I could check?
Protein table:
describe protein output:
+---------------------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------------------+---------+------+-----+---------+-------+
| PID | int(11) | NO | PRI | NULL | |
| uniprot_UniprotAC | char(6) | YES | MUL | NULL | |
| pubmedhits_id | int(11) | YES | MUL | NULL | |
| internallyDefinedNames_id | int(11) | YES | MUL | NULL | |
| comment | int(11) | YES | MUL | NULL | |
+---------------------------+---------+------+-----+---------+-------+
show create table protein output:
CREATE TABLE `protein` (
`PID` int(11) NOT NULL,
`uniprot_UniprotAC` char(6) COLLATE utf8_unicode_ci DEFAULT NULL,
`pubmedhits_id` int(11) DEFAULT NULL,
`internallyDefinedNames_id` int(11) DEFAULT NULL,
`comment` int(11) DEFAULT NULL,
PRIMARY KEY (`PID`),
KEY `fk_protein_uniprot1_idx` (`uniprot_UniprotAC`),
KEY `fk_protein_pubmedhits1_idx` (`pubmedhits_id`),
KEY `fk_protein_internallyDefinedNames1_idx` (`internallyDefinedNames_id`),
KEY `fk_protein_comments1_idx` (`comment`),
CONSTRAINT `protein_ibfk_4` FOREIGN KEY (`uniprot_UniprotAC`) REFERENCES `uniprot` (`UniprotAC`),
CONSTRAINT `protein_ibfk_1` FOREIGN KEY (`comment`) REFERENCES `comments` (`idcomments`),
CONSTRAINT `protein_ibfk_2` FOREIGN KEY (`internallyDefinedNames_id`) REFERENCES `internallydefinednames` (`id`),
CONSTRAINT `protein_ibfk_3` FOREIGN KEY (`pubmedhits_id`) REFERENCES `pubmedhits` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
ag table:
describe ag:
+-------------+--------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------------------------+------+-----+---------+-------+
| Article_AID | mediumint(5) unsigned zerofill | NO | PRI | NULL | |
| Name | varchar(200) | YES | | NULL | |
| Form | varchar(150) | YES | | NULL | |
| Mw | varchar(40) | YES | | NULL | |
| Source | varchar(260) | YES | | NULL | |
| protein_PID | int(11) | YES | | NULL | |
+-------------+--------------------------------+------+-----+---------+-------+
show create table ag:
`ag` (
`Article_AID` mediumint(5) unsigned zerofill NOT NULL,
`Name` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL,
`Form` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
`Mw` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
`Source` varchar(260) COLLATE utf8_unicode_ci DEFAULT NULL,
`protein_PID` int(11) DEFAULT NULL,
PRIMARY KEY (`Article_AID`),
KEY `fk_ag_Article1_idx` (`Article_AID`),
CONSTRAINT `fk_ag_Article1` FOREIGN KEY (`Article_AID`) REFERENCES `article` (`AID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
I figured out what the problem was. In the ag table the protein_PID column was added when there was already data in the table and when it was first created it was set to be not null. Then the rows where all set to 0 for protein_PID as default and since there was no data in protein I could not add the foreign key.
Make PID and protein_PID both to not NULL
May this will solve your issue