Cannot Add Foreign Key Constraint - I Checked almost everything - mysql

okay, so im having a weird issue with this foreign key constraint.
The data type is Int(11) and all tables and databases are using utf8_general_ci but I'm still getting an issue! the only table that inherited the Medicine_ID is the First Aid table.
Here's my schema:
tbl_Medicine
+--------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| Medicine_ID | int(11) | NO | PRI | NULL | |
| Brand_Name | varchar(45) | YES | | NULL | |
| Generic_Name | varchar(45) | YES | | NULL | |
| Countable | int(11) | YES | | NULL | |
+--------------+-------------+------+-----+---------+-------+
tbl_batch
+---------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------+------+-----+---------+-------+
| Batch_ID | int(11) | NO | PRI | NULL | |
| Purchase_Date | date | YES | | NULL | |
+---------------+---------+------+-----+---------+-------+
tbl_Stock
+-----------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------+------+-----+---------+-------+
| Stock_ID | int(11) | NO | PRI | NULL | |
| Medicine_ID | int(11) | NO | PRI | NULL | |
| Batch_ID | int(11) | NO | PRI | NULL | |
| Expiration_Date | date | YES | | NULL | |
| Quantity | int(45) | YES | | NULL | |
| Unit_Price | int(11) | YES | | NULL | |
+-----------------+---------+------+-----+---------+-------+
tbl_inventory
+--------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| Inventory_ID | int(11) | NO | PRI | NULL | |
| Building | varchar(45) | NO | PRI | NULL | |
| Stock_ID | int(11) | NO | PRI | NULL | |
| Medicine_ID | int(11) | NO | PRI | NULL | |
| Quantity | varchar(45) | YES | | NULL | |
+--------------+-------------+------+-----+---------+-------+
tbl_Activity
+--------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| Activity_ID | varchar(10) | NO | PRI | NULL | |
| Purpose | varchar(50) | YES | | NULL | |
| Organization | varchar(50) | YES | | NULL | |
| Reciever | varchar(50) | YES | | NULL | |
| Recieve_Date | date | YES | | NULL | |
| Act_Date | date | YES | | NULL | |
| Validator | varchar(10) | YES | | NULL | |
+--------------+-------------+------+-----+---------+-------+
Heres the creation query:
CREATE TABLE IF NOT EXISTS `csb_inventory`.`tbl_batch` (
`Batch_ID` INT(11) NOT NULL COMMENT '',
`Purchase_Date` DATE NULL DEFAULT NULL COMMENT '',
PRIMARY KEY (`Batch_ID`) COMMENT '')
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
CREATE TABLE IF NOT EXISTS `csb_inventory`.`tbl_medicine` (
`Medicine_ID` INT(11) NOT NULL COMMENT '',
`Brand_Name` VARCHAR(45) NULL DEFAULT NULL COMMENT '',
`Generic_Name` VARCHAR(45) NULL DEFAULT NULL COMMENT '',
`Countable` INT(11) NULL DEFAULT NULL COMMENT '',
PRIMARY KEY (`Medicine_ID`) COMMENT '')
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
CREATE TABLE IF NOT EXISTS `csb_inventory`.`tbl_stock` (
`Stock_ID` INT(11) NOT NULL COMMENT '',
`Medicine_ID` INT(11) NOT NULL COMMENT '',
`Batch_ID` INT(11) NOT NULL COMMENT '',
`Expiration_Date` DATE NULL DEFAULT NULL COMMENT '',
`Quantity` INT(45) NULL DEFAULT NULL COMMENT '',
`Unit_Price` INT(11) NULL DEFAULT NULL COMMENT '',
PRIMARY KEY (`Stock_ID`, `Medicine_ID`, `Batch_ID`) COMMENT '',
INDEX `fk_tbl_Stock_tbl_Medicine_idx` (`Medicine_ID` ASC) COMMENT '',
INDEX `fk_tbl_Stock_tbl_Batch1_idx` (`Batch_ID` ASC) COMMENT '',
CONSTRAINT `batch`
FOREIGN KEY (`Batch_ID`)
REFERENCES `csb_inventory`.`tbl_batch` (`Batch_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `medicine`
FOREIGN KEY (`Medicine_ID`)
REFERENCES `csb_inventory`.`tbl_medicine` (`Medicine_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
CREATE TABLE IF NOT EXISTS `csb_inventory`.`tbl_inventory` (
`Inventory_ID` INT(11) NOT NULL COMMENT '',
`Building` VARCHAR(45) NOT NULL COMMENT '',
`Stock_ID` INT(11) NOT NULL COMMENT '',
`Medicine_ID` INT(11) NOT NULL COMMENT '',
`Quantity` VARCHAR(45) NULL DEFAULT NULL COMMENT '',
PRIMARY KEY (`Inventory_ID`, `Building`, `Stock_ID`, `Medicine_ID`) COMMENT '',
INDEX `fk_tbl_Inventory_tbl_Building1_idx` (`Building` ASC) COMMENT '',
INDEX `fk_tbl_Inventory_tbl_Stock1_idx` (`Stock_ID` ASC, `Medicine_ID` ASC) COMMENT '',
CONSTRAINT `building`
FOREIGN KEY (`Building`)
REFERENCES `csb_patient`.`tbl_building` (`Building`),
CONSTRAINT `stockitem`
FOREIGN KEY (`Stock_ID` , `Medicine_ID`)
REFERENCES `csb_inventory`.`tbl_stock` (`Stock_ID` , `Medicine_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
CREATE TABLE IF NOT EXISTS `csb_inventory`.`tbl_firstaid` (
`FirstAid_ID` VARCHAR(10) NOT NULL COMMENT '',
`Activity_ID` VARCHAR(10) NOT NULL COMMENT '',
`Quantity` SMALLINT(6) NOT NULL COMMENT '',
`Inventory_ID` INT(11) NOT NULL COMMENT '',
`Medicine_ID` INT(11) NOT NULL COMMENT '',
PRIMARY KEY (`FirstAid_ID`, `Activity_ID`, `Inventory_ID`, `Medicine_ID`) COMMENT '',
INDEX `activity_id` (`Activity_ID` ASC) COMMENT '',
INDEX `fk_tbl_firstaid_tbl_inventory1_idx` (`Inventory_ID` ASC, `Medicine_ID` ASC) COMMENT '',
CONSTRAINT `activity_id`
FOREIGN KEY (`Activity_ID`)
REFERENCES `csb_inventory`.`tbl_activity` (`Activity_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_tbl_firstaid_tbl_inventory1`
FOREIGN KEY (`Inventory_ID` , `Medicine_ID`)
REFERENCES `csb_inventory`.`tbl_inventory` (`Inventory_ID` , `Medicine_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
I have read alot of threads regarding the same issue and tested them out.
I made sure that im using the same table_type, collation, and data_type. I even checked all other tables that are related that might have been causing the issue but no good. I was able to successfully add foreign keys to firstAid but only the Medicine_ID is the one failing.
help? xD

Make sure that you have tbl_building on before create tbl_inventory.

Related

Mysql, slow avg query

I have a single table book_log Mysql 5.7
+------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| book_id | int(11) | YES | MUL | NULL | |
| type | int(11) | NO | MUL | NULL | |
| value | int(11) | YES | | NULL | |
| created_at | datetime | NO | | NULL | |
+------------+----------+------+-----+---------+----------------+
Book table makes connection with series (One series can have many books)
Create table info :
book_log | CREATE TABLE `book_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`book_id` int(11) DEFAULT NULL,
`type` int(11) NOT NULL,
`value` int(11) DEFAULT NULL,
`created_at` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `IDX_7E42115316A2B381` (`book_id`),
KEY `IDX_TYPE` (`type`),
KEY `IDX_ME` (`book_id`,`type`) USING BTREE,
CONSTRAINT `FK_7E42115316A2B381` FOREIGN KEY (`book_id`) REFERENCES `book` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1158962 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
book | CREATE TABLE `book` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`series_id` int(11) DEFAULT NULL,
`language_id` int(11) DEFAULT NULL,
`position` int(11) NOT NULL,
`dir` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `IDX_CBE5A3315278319C` (`series_id`),
KEY `IDX_CBE5A33182F1BAF4` (`language_id`),
CONSTRAINT `FK_CBE5A3315278319C` FOREIGN KEY (`series_id`) REFERENCES `series` (`id`),
CONSTRAINT `FK_CBE5A33182F1BAF4` FOREIGN KEY (`language_id`) REFERENCES `language` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=55022 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
I make the avg value for a given series
select AVG(value)
from book_log
join book b on book_log.book_id = b.id
where type = 20 and b.series_id = ?;
Explain :
+----+-------------+----------+------------+------+------------------------------+----------------------+---------+----------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+------------------------------+----------------------+---------+----------------+------+----------+-------------+
| 1 | SIMPLE | b | NULL | ref | PRIMARY,IDX_CBE5A3315278319C | IDX_CBE5A3315278319C | 5 | const | 212 | 100.00 | Using index |
| 1 | SIMPLE | book_log | NULL | ref | IDX_7E42115316A2B381,IDX_ME | IDX_7E42115316A2B381 | 5 | bdd.b.id | 33 | 100.00 | NULL |
+----+-------------+----------+------------+------+------------------------------+----------------------+---------+----------------+------+----------+-------------+
Or
select AVG(value)
from book_log
where type = 20 AND book_id IN (
select id from book where series_id = ?
);
Explain :
+----+-------------+----------+------------+------+--------------------------------------+----------------------+---------+-------------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+--------------------------------------+----------------------+---------+-------------------+------+----------+-------------+
| 1 | SIMPLE | book | NULL | ref | PRIMARY,IDX_CBE5A3315278319C | IDX_CBE5A3315278319C | 5 | const | 212 | 100.00 | Using index |
| 1 | SIMPLE | book_log | NULL | ref | IDX_7E42115316A2B381,IDX_TYPE,IDX_ME | IDX_7E42115316A2B381 | 5 | bdd.book.id | 33 | 3.72 | Using where |
+----+-------------+----------+------------+------+--------------------------------------+----------------------+---------+-------------------+------+----------+-------------+
I have 10 973 results for these query, 42ms for a count(*) but more than 1 sec for the avg query.
I don't understand why is it so long.
Any idea ?
Thx.
You can expect to COUNT(*) be as fast or faster than SUM(somecol) or AVG(othercolumn). Why? The database server is, by the rules of SQL, to apply any optimization that yields the correct anwer. COUNT(*) has some serious optimization to it.
But the aggregate functions that do arithmetic ; they must instead examine every record. So, slower.
You can create a purpose-built index for your query.
It is this:
ALTER TABLE book_log
ADD INDEX type_id_val
(type, book_id, val)
I chose these columns for the index because your query searches for a particuler type in the index. Upon finding the first row of the chosen type, MySQL can range-scan through just the index and not the table. So, faster. It's called a covering index.

Slow query on smaller MySQL server

I am running MySQL 5.7 on both my server and my local machine. I am using Symfony 4.4 and Doctrine.
On my dev machine the following query (with the same DB dumped from the server) executes in ~2s, while it takes 35s+ on the server.
I assume this is linked to limitations of the server (less RAM, etc.) but I can't really throw additional memory in there. Therefore, I am looking at how I could improve the following the query - originally generated by Doctrine.
I replicated the same slowness by executing the same query directly in phpMyAdmin on the server so I know for sure the query is responsible.
I am a bit stuck here and would appreciate any help or pointers in the right direction: Do I need to try to split the queries? Should I try to add indexes (besides the PK and FK the column referenced in the where clause are not indexed) ?
Thank you all for the help!
SELECT DISTINCT id_0 FROM (
SELECT DISTINCT id_0, pivot_price_5 FROM (
SELECT b0_.id AS id_0, b0_.price_drop AS price_drop_1, o1_.id AS id_2, o1_.price AS price_3, o1_.currency AS currency_4, o1_.pivot_price AS pivot_price_5, o1_.price_drop AS price_drop_6, o1_.date AS date_7, p2_.id AS id_8, p2_.name AS name_9, p2_.description AS description_10, p2_.normal_price AS normal_price_11, p2_.link AS link_12, p2_.image_link AS image_link_13, p2_.image_thumb_link AS image_thumb_link_14, p2_.merchant_product_id AS merchant_product_id_15, p2_.slug AS slug_16, p2_.created_at AS created_at_17, p2_.updated_at AS updated_at_18, p3_.id AS id_19, p3_.ean AS ean_20, p3_.last_game_check_date AS last_game_check_date_21, p3_.created_at AS created_at_22, p3_.updated_at AS updated_at_23, g4_.id AS id_24, g4_.game_system_key AS game_system_key_25, g4_.created_at AS created_at_26, g4_.updated_at AS updated_at_27
FROM best_offer b0_
INNER JOIN offer o1_ ON b0_.offer_id = o1_.id
INNER JOIN product_version p2_ ON o1_.product_version_id = p2_.id
INNER JOIN product p3_ ON b0_.product_id = p3_.id
INNER JOIN product_game_system p5_ ON p3_.id = p5_.product_id
INNER JOIN game_system g4_ ON g4_.id = p5_.game_system_id
WHERE (o1_.date >= '2020-07-29 00:00:00' AND o1_.date <= '2020-07-29 23:59:59')
AND o1_.pivot_price >= '0'
AND o1_.pivot_price <= '2208'
AND g4_.game_system_key IN ('NSW', 'PS4', 'ONE')
) dctrn_result_inner
ORDER BY pivot_price_5 ASC
) dctrn_result LIMIT 8 OFFSET 40
For completion sake, the PHP code is:
// In Repository
$qb = $this->createQueryBuilder('best_offer')
->join('best_offer.offer', 'offer')
->addSelect('offer')
->join('offer.productVersion', 'productVersion')
->addSelect('productVersion')
->join('best_offer.product', 'product')
->addSelect('product')
->join('product.gameSystems', 'gameSystems')
->addSelect('gameSystems')
;
$qb
->join('product.game', 'game')
->join('game.ratings', 'game_ratings')
->andWhere('game_ratings.type = :gameRatingType')
->setParameter('gameRatingType', GameRating::TYPE_METACRITIC)
->andWhere('game_ratings.rating > :gameRatingValue')
->setParameter('gameRatingValue', $minMetacritic)
;
$qb = $qb->addCriteria(OfferRepository::createCriteriaOnDate($datetime, 'offer'));
$qb->andWhere('offer.pivotPrice >= :minPivotPrice')
->setParameter('minPivotPrice', $minPivotPrice*100)
;
$qb = $qb->addCriteria(OfferRepository::createCriteriaMaxPivotPrice($maxPivotPrice, 'offer'));
$qb = $qb->addCriteria(GameSystemRepository::createCriteriaSystemsIn($gameSystems, 'gameSystems'));
$qb = $qb->setMaxResults($limit);
foreach ($sortBy as $sortKey => $sortValue) {
$qb = $qb->orderBy($sortKey, $sortValue);
}
return $qb;
called by the PagerFanta in the Controller:
// In Controller
$adapter = new DoctrineORMAdapter($qb);
$pagerFanta = new Pagerfanta($adapter);
$pagerFanta->setMaxPerPage(8);
$pagerFanta->setCurrentPage($page);
Explain results:
+----+-------------+------------+------------+--------+--------------------------------------------------+-----------------------+---------+--------------------------------+------+----------+-----------------------------------------------------------+--+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | |
+----+-------------+------------+------------+--------+--------------------------------------------------+-----------------------+---------+--------------------------------+------+----------+-----------------------------------------------------------+--+
| 1 | PRIMARY | <derived2> | NULL | ALL | NULL | NULL | NULL | NULL | 2268 | 100.00 | Using temporary | |
| 2 | DERIVED | g4_ | NULL | range | PRIMARY,UNIQ_B478BC43A9F4C69F | UNIQ_B478BC43A9F4C69F | 14 | NULL | 3 | 100.00 | Using where; Using index; Using temporary; Using filesort | |
| 2 | DERIVED | p5_ | NULL | ref | PRIMARY,IDX_1857225C4584665A,IDX_1857225C233EEA7 | IDX_1857225C233EEA7 | 4 | vgdeals.g4_.id | 377 | 100.00 | Using index | |
| 2 | DERIVED | p3_ | NULL | eq_ref | PRIMARY | PRIMARY | 4 | vgdeals.p5_.product_id | 1 | 100.00 | Using index | |
| 2 | DERIVED | b0_ | NULL | ref | UNIQ_8B8D09A53C674EE,IDX_8B8D09A4584665A | IDX_8B8D09A4584665A | 4 | vgdeals.p5_.product_id | 40 | 100.00 | NULL | |
| 2 | DERIVED | o1_ | NULL | eq_ref | PRIMARY,IDX_29D6873ED8DB782E | PRIMARY | 4 | vgdeals.b0_.offer_id | 1 | 5.00 | Using where | |
| 2 | DERIVED | p2_ | NULL | eq_ref | PRIMARY | PRIMARY | 4 | vgdeals.o1_.product_version_id | 1 | 100.00 | Using index | |
+----+-------------+------------+------------+--------+--------------------------------------------------+-----------------------+---------+--------------------------------+------+----------+-----------------------------------------------------------+--+
The SHOW CREATE TABLE for the involved tables is below (sorry I couldn't find a way to format this properly in SO):
BEST_OFFER
CREATE TABLE `best_offer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) NOT NULL,
`offer_id` int(11) NOT NULL,
`price_drop` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_8B8D09A53C674EE` (`offer_id`),
KEY `IDX_8B8D09A4584665A` (`product_id`),
CONSTRAINT `FK_8B8D09A4584665A` FOREIGN KEY (`product_id`) REFERENCES `product` (`id`),
CONSTRAINT `FK_8B8D09A53C674EE` FOREIGN KEY (`offer_id`) REFERENCES `offer` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=317260 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
OFFER
CREATE TABLE `offer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`product_version_id` int(11) NOT NULL,
`price` int(10) unsigned NOT NULL,
`currency` varchar(3) COLLATE utf8mb4_unicode_ci NOT NULL,
`pivot_price` int(11) NOT NULL,
`price_drop` int(11) DEFAULT NULL,
`date` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `IDX_29D6873ED8DB782E` (`product_version_id`),
CONSTRAINT `FK_29D6873ED8DB782E` FOREIGN KEY (`product_version_id`) REFERENCES `product_version` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=497233 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
PRODUCT_VERSION
CREATE TABLE `product_version` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`merchant_id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` longtext COLLATE utf8mb4_unicode_ci,
`normal_price` int(10) unsigned DEFAULT NULL,
`link` varchar(4000) COLLATE utf8mb4_unicode_ci NOT NULL,
`image_link` varchar(4000) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`image_thumb_link` varchar(4000) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`merchant_product_id` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
`slug` varchar(300) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_6EC5C873989D9B62` (`slug`),
KEY `IDX_6EC5C8736796D554` (`merchant_id`),
KEY `IDX_6EC5C8734584665A` (`product_id`),
CONSTRAINT `FK_6EC5C8734584665A` FOREIGN KEY (`product_id`) REFERENCES `product` (`id`),
CONSTRAINT `FK_6EC5C8736796D554` FOREIGN KEY (`merchant_id`) REFERENCES `merchant` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10775 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
PRODUCT
CREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ean` char(13) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`game_id` int(11) DEFAULT NULL,
`last_game_check_date` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_D34A04AD67B1C660` (`ean`),
KEY `IDX_D34A04ADE48FD905` (`game_id`),
CONSTRAINT `FK_D34A04ADE48FD905` FOREIGN KEY (`game_id`) REFERENCES `game` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6450 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
PRODUCT_GAME_SYSTEM
CREATE TABLE `product_game_system` (
`product_id` int(11) NOT NULL,
`game_system_id` int(11) NOT NULL,
PRIMARY KEY (`product_id`,`game_system_id`),
KEY `IDX_1857225C4584665A` (`product_id`),
KEY `IDX_1857225C233EEA7` (`game_system_id`),
CONSTRAINT `FK_1857225C233EEA7` FOREIGN KEY (`game_system_id`) REFERENCES `game_system` (`id`) ON DELETE CASCADE,
CONSTRAINT `FK_1857225C4584665A` FOREIGN KEY (`product_id`) REFERENCES `product` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
GAME_SYSTEM
CREATE TABLE `game_system` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`game_system_key` varchar(3) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UNIQ_B478BC43A9F4C69F` (`game_system_key`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
Finally, here is the SHOW TABLE STATUS
+---------------------+--------+----+---------+--------+------+----------+---+---------+---------+--------+---------------------+---------------------+---------------------+---------------------+--+--------------------+--+--------------------+--+----------+--+--+--+--+
| best_offer | InnoDB | 10 | Dynamic | 307651 | 46 | 14172160 | 0 | 9469952 | 5242880 | 317260 | 2020-07-29 22:16:33 | 2020-07-31 07:59:09 | | NULL | | utf8mb4_unicode_ci | | NULL | | | | | | |
+---------------------+--------+----+---------+--------+------+----------+---+---------+---------+--------+---------------------+---------------------+---------------------+---------------------+--+--------------------+--+--------------------+--+----------+--+--+--+--+
| game_system | InnoDB | 10 | Dynamic | 17 | 963 | 16384 | 0 | 16384 | 0 | 18 | 2020-07-29 22:16:36 | | NULL | | | NULL | | utf8mb4_unicode_ci | | NULL | | | | |
| offer | InnoDB | 10 | Dynamic | 460330 | 60 | 27836416 | 0 | 7880704 | 6291456 | 497233 | 2020-07-29 22:16:44 | 2020-07-31 07:59:09 | | NULL | | utf8mb4_unicode_ci | | NULL | | | | | | |
| product | InnoDB | 10 | Dynamic | 6432 | 63 | 409600 | 0 | 294912 | 0 | 6450 | 2020-07-29 22:16:44 | 2020-07-31 08:00:57 | | NULL | | utf8mb4_unicode_ci | | NULL | | | | | | |
| product_game_system | InnoDB | 10 | Dynamic | 6419 | 33 | 212992 | 0 | 229376 | 0 | | NULL | | 2020-07-29 22:16:44 | 2020-07-31 07:57:15 | | NULL | | utf8mb4_unicode_ci | | NULL | | | | |
| product_version | InnoDB | 10 | Dynamic | 10749 | 2297 | 24690688 | 0 | 1916928 | 7340032 | 10775 | 2020-07-29 22:16:50 | 2020-07-31 07:59:00 | | NULL | | utf8mb4_unicode_ci | | NULL | | | | | | |
+---------------------+--------+----+---------+--------+------+----------+---+---------+---------+--------+---------------------+---------------------+---------------------+---------------------+--+--------------------+--+--------------------+--+----------+--+--+--+--+
The ORDER BY pivot_price_5 ASC is useless. This is because a subquery is, but definition, an unordered set. (Adding a LIMIT makes it no useless.) But it seems like you should get rid of the inner subquery.
DISTINCT with LIMIT -- you are aware that the DISTINCT happens first?
There are two ranges and one IN in the main WHERE; only one of them can use an index. I suggest you have each of thefollowing so that the Optimizer can pick the better. (Note: With a different dataset, the Optimizer may pick a different INDEX, with different performance.)
INDEX(pivot_price)
INDEX(date)
Please provide EXPLAINs, CREATE TABLEs, and SHOW TABLE STATUS. (I want to analyze whether using partitioning for your "2-dimensional" WHERE would be worth pursuing.)
It looks like you are fetching several columns from many of the tables, only to eventually ignore those extra columns. Cleaning that up will help performance.

How can I delete the repeated data in MYSQL with over ten million data in it?

I crawed lots of data, and saved it into mysql table, but there're some data duplicated, and I want to delete them in a effective way.
table (ads_info)
+------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| ad_id | varchar(64) | YES | MUL | NULL | |
| adset_id | varchar(64) | YES | MUL | NULL | |
| campaign_id | varchar(64) | YES | | NULL | |
| account_id | varchar(64) | YES | MUL | NULL | |
| conversion_specs | text | YES | | NULL | |
| creative | text | YES | | NULL | |
| effective_status | varchar(32) | YES | | NULL | |
| status | varchar(32) | YES | | NULL | |
| name | varchar(255) | YES | | NULL | |
| tracking_specs | text | YES | | NULL | |
| object_store_url | varchar(255) | YES | | NULL | |
| link | varchar(255) | YES | | NULL | |
| object_type | varchar(32) | YES | | NULL | |
| updated_time | timestamp | YES | | NULL | |
| created_time | timestamp | YES | | NULL | |
+------------------+--------------+------+-----+---------+----------------+
show create table ads_info
CREATE TABLE `ads_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ad_id` varchar(64) DEFAULT NULL,
`adset_id` varchar(64) DEFAULT NULL,
`campaign_id` varchar(64) DEFAULT NULL,
`account_id` varchar(64) DEFAULT NULL,
`conversion_specs` text,
`creative` text,
`effective_status` varchar(32) DEFAULT NULL,
`status` varchar(32) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`tracking_specs` text,
`object_store_url` varchar(255) DEFAULT NULL,
`link` varchar(255) DEFAULT NULL,
`object_type` varchar(32) DEFAULT NULL,
`updated_time` timestamp NULL DEFAULT NULL,
`created_time` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `ad_id` (`ad_id`),
KEY `adset_id` (`adset_id`),
KEY `account_id` (`account_id`)
) ENGINE=InnoDB AUTO_INCREMENT=18827534 DEFAULT CHARSET=utf8mb4
There're over ten million ad info in the table, and about 40 thusand repeated. And I want delete all those repeated data.
Here's my poor trial
1)select all repeated ad_id
select ad_id from ads_info group by ad_id having count(id) > 1;
#42387 rows in set (12.42 sec)
The query cost 12s, but I don't know how to do an optimization.
2) use subquery to delete all these repeated data.
delete from ads_info where ad_id in ( select ad_id from (select ad_id from ads_info group by ad_id having count(id) > 1) t);
But I failed to get response from mysql with this trial, it seemed to be hanged with the query.
How can I delete these repeated data?
You needed a UNIQUE key in the first place. This will add it and dedup:
ALTER IGNORE TABLE ads_info
ADD UNIQUE KEY(ad_id);
If you want delete all the occurence then
Instead of IN clause you could try using a join
delete ads_info
from ads_info
INNER JOIN (
select ad_id
from ads_info
group by ad_id
having count(*) > 1
) T ON T.ad_id = ads_info.ad_id
be sure you have and index on ads_info.ad_id
if you have index .. but the query optimizer don't use and you are sure is a valid index you could try using USE or FORCE
delete ads_info
from ads_info
INNER JOIN (
select ad_id
from ads_info
group by ad_id
having count(*) > 1
) T FORCE INDEX FOR JOIN (`ad_id`) ON T.ad_id = ads_info.ad_id

Mysql wrong index after InnoDB compression

I have 2 mysql servers (master and slave). I've enabled InnoDB compression on Slave, after that mysql sometimes chooses wrong index on query.
Explain on Master:
+----+-------------+-------+--------+---------------+---------+---------+-----------------------------+-----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+-----------------------------+-----------+-------------+
| 1 | SIMPLE | p | range | PRIMARY | PRIMARY | 8 | NULL | 112017572 | Using where |
| 1 | SIMPLE | l | eq_ref | PRIMARY | PRIMARY | 8 | p.loan_ID | 1 | NULL |
| 1 | SIMPLE | af | eq_ref | PRIMARY | PRIMARY | 8 | p.fromAccount_ID | 1 | Using where |
| 1 | SIMPLE | at | eq_ref | PRIMARY | PRIMARY | 8 | p.toAccount_ID | 1 | Using where |
+----+-------------+-------+--------+---------------+---------+---------+-----------------------------+-----------+-------------+
Explain on Slave:
+----+-------------+-------+--------+-------------------------------------------------------------------------------+--------------------+---------+-----------------------------+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+-------------------------------------------------------------------------------+--------------------+---------+-----------------------------+--------+----------------------------------------------+
| 1 | SIMPLE | l | index | PRIMARY | FK243910AAD869E6 | 9 | NULL | 804876 | Using index; Using temporary; Using filesort |
| 1 | SIMPLE | p | ref | PRIMARY,FK4BE7532292C5D482,FK4BE75322AE503A13,FK4BE75322382D11BC,POSTING_DATE | FK4BE75322382D11BC | 9 | l.ID | 101 | Using index condition; Using where |
| 1 | SIMPLE | af | eq_ref | PRIMARY | PRIMARY | 8 | p.fromAccount_ID | 1 | Using where |
| 1 | SIMPLE | at | eq_ref | PRIMARY | PRIMARY | 8 | p.toAccount_ID | 1 | Using where |
+----+-------------+-------+--------+-------------------------------------------------------------------------------+--------------------+---------+-----------------------------+--------+----------------------------------------------+
SELECT
p.ID AS 'payment_id',
p.loan_ID AS 'loan_id',
l.client_ID AS 'client_ID',
p.amount AS 'amount',
p.postingDate AS 'payment_date',
CASE
WHEN af.acc_type = 'POLCH' THEN 'wallet'
WHEN af.acc_type = 'PLTCH' THEN 'wallet'
WHEN af.acc_type = 'CNTT' THEN 'bank'
WHEN af.acc_type = 'CNT2' THEN 'bank'
WHEN af.acc_type = 'KONCH' THEN 'bank'
WHEN af.acc_type = 'KRDTM' THEN 'cash'
WHEN af.acc_type = 'LDRCH' THEN 'bank'
ELSE concat('UNKNOWN_',af.acc_type)
END AS 'payment_system_type',
af.description AS 'payment_system'
FROM Posting AS p
INNER JOIN Account AS af ON p.fromAccount_ID = af.ID
INNER JOIN Account AS at ON p.toAccount_ID = at.ID
INNER JOIN Loan AS l ON p.loan_id = l.ID
WHERE (
af.acc_type = 'KONCH'
OR af.acc_type = 'PLTCH'
OR af.acc_type = 'POLCH'
OR af.acc_type = 'KRDTM'
OR af.acc_type = 'LDRCH'
OR af.acc_type = 'CNT2'
OR af.acc_type = 'CNTT')
AND at.acc_type = 'ABON'
AND p.postingDate < DATE(now())
AND p.ID > 0
ORDER BY p.ID LIMIT 10000;
Loan - l
Posting - P
Master:
| Loan | CREATE TABLE `Loan` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`amount` decimal(19,4) DEFAULT NULL,
`amountToReturn` decimal(19,4) DEFAULT NULL,
`isGivenOut` bit(1) DEFAULT b'0',
`isPaid` bit(1) DEFAULT NULL,
`issueDate` datetime DEFAULT NULL,
`loanPeriod` int(11) DEFAULT NULL,
`productType` varchar(255) DEFAULT NULL,
`realPayDate` datetime DEFAULT NULL,
`client_ID` bigint(20) DEFAULT NULL,
`product_ID` bigint(20) DEFAULT NULL,
`givenOutDate` datetime DEFAULT NULL,
`isPaidByBank` bit(1) DEFAULT NULL,
`accountNumberNBKI` varchar(255) DEFAULT NULL,
`needManualProcessing` bit(1) DEFAULT NULL,
`isReverted` bit(1) DEFAULT b'0',
`showInNBCHReport` bit(1) DEFAULT b'1',
`stake` decimal(19,5) DEFAULT NULL,
`ignoreProlongation` bit(1) DEFAULT b'0',
`stakeAfter21` decimal(19,5) DEFAULT NULL,
`discount_id` bigint(20) DEFAULT NULL,
`showInEquifaxReport` bit(1) DEFAULT b'1',
`ignoreNbch` bit(1) DEFAULT b'0',
PRIMARY KEY (`ID`),
KEY `FK2439106EC0BA18` (`product_ID`),
KEY `ISPAID_INDEX` (`isPaid`) USING BTREE,
KEY `ISP_ISGOUT_INDEX` (`isPaid`,`isGivenOut`),
KEY `ISSUEDATE_INDEX` (`issueDate`),
KEY `FK243910735827C6` (`discount_id`),
KEY `idx_Loan_realPayDate` (`realPayDate`),
KEY `idx_Loan_givenOutDate` (`givenOutDate`),
KEY `FK243910AAD869E6` (`client_ID`),
CONSTRAINT `_FK243910735827C6` FOREIGN KEY (`discount_id`) REFERENCES `Discount` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2000623399 DEFAULT CHARSET=utf8
Posting | CREATE TABLE `Posting` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`amount` decimal(19,4) DEFAULT NULL,
`postingDate` datetime DEFAULT NULL,
`fromAccount_ID` bigint(20) DEFAULT NULL,
`loan_ID` bigint(20) DEFAULT NULL,
`toAccount_ID` bigint(20) DEFAULT NULL,
`sourceType` varchar(255) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `FK4BE7532292C5D482` (`fromAccount_ID`),
KEY `FK4BE75322AE503A13` (`toAccount_ID`),
KEY `FK4BE75322382D11BC` (`loan_ID`),
KEY `POSTING_DATE` (`postingDate`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=230996702 DEFAULT CHARSET=utf8
Slave:
| Loan | CREATE TABLE `Loan` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`amount` decimal(19,4) DEFAULT NULL,
`amountToReturn` decimal(19,4) DEFAULT NULL,
`isGivenOut` bit(1) DEFAULT b'0',
`isPaid` bit(1) DEFAULT NULL,
`issueDate` datetime DEFAULT NULL,
`loanPeriod` int(11) DEFAULT NULL,
`productType` varchar(255) DEFAULT NULL,
`realPayDate` datetime DEFAULT NULL,
`client_ID` bigint(20) DEFAULT NULL,
`product_ID` bigint(20) DEFAULT NULL,
`givenOutDate` datetime DEFAULT NULL,
`isPaidByBank` bit(1) DEFAULT NULL,
`accountNumberNBKI` varchar(255) DEFAULT NULL,
`needManualProcessing` bit(1) DEFAULT NULL,
`isReverted` bit(1) DEFAULT b'0',
`showInNBCHReport` bit(1) DEFAULT b'1',
`stake` decimal(19,5) DEFAULT NULL,
`ignoreProlongation` bit(1) DEFAULT b'0',
`stakeAfter21` decimal(19,5) DEFAULT NULL,
`discount_id` bigint(20) DEFAULT NULL,
`showInEquifaxReport` bit(1) DEFAULT b'1',
`ignoreNbch` bit(1) DEFAULT b'0',
PRIMARY KEY (`ID`),
KEY `FK2439106EC0BA18` (`product_ID`),
KEY `ISPAID_INDEX` (`isPaid`) USING BTREE,
KEY `ISP_ISGOUT_INDEX` (`isPaid`,`isGivenOut`),
KEY `ISSUEDATE_INDEX` (`issueDate`),
KEY `FK243910735827C6` (`discount_id`),
KEY `idx_Loan_realPayDate` (`realPayDate`),
KEY `idx_Loan_givenOutDate` (`givenOutDate`),
KEY `FK243910AAD869E6` (`client_ID`),
CONSTRAINT `_FK243910735827C6` FOREIGN KEY (`discount_id`) REFERENCES `Discount` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2000623399 DEFAULT CHARSET=utf8
ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4
Posting | CREATE TABLE `Posting` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`amount` decimal(19,4) DEFAULT NULL,
`postingDate` datetime DEFAULT NULL,
`fromAccount_ID` bigint(20) DEFAULT NULL,
`loan_ID` bigint(20) DEFAULT NULL,
`toAccount_ID` bigint(20) DEFAULT NULL,
`sourceType` varchar(255) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `FK4BE7532292C5D482` (`fromAccount_ID`),
KEY `FK4BE75322AE503A13` (`toAccount_ID`),
KEY `FK4BE75322382D11BC` (`loan_ID`),
KEY `POSTING_DATE` (`postingDate`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=230996702 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4
If remove table Loan from Query
+----+-------------+-------+--------+------------------------------------------------------------+---------+---------+-----------------------------+-----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+------------------------------------------------------------+---------+---------+-----------------------------+-----------+-------------+
| 1 | SIMPLE | p | range | PRIMARY,FK4BE7532292C5D482,FK4BE75322AE503A13,POSTING_DATE | PRIMARY | 8 | NULL | 107736559 | Using where |
| 1 | SIMPLE | af | eq_ref | PRIMARY | PRIMARY | 8 | smsfinance.p.fromAccount_ID | 1 | Using where |
| 1 | SIMPLE | at | eq_ref | PRIMARY | PRIMARY | 8 | smsfinance.p.toAccount_ID | 1 | Using where |
+----+-------------+-------+--------+------------------------------------------------------------+---------+---------+-----------------------------+-----------+-------------+
If I add
create index acc on Account(acc_type);
Plan:
+----+-------------+-------+--------+-------------------------------------------------------------------------------+--------------------+---------+---------------------------+------+--------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+-------------------------------------------------------------------------------+--------------------+---------+---------------------------+------+--------------------------------------------------------+
| 1 | SIMPLE | af | range | PRIMARY,acc | acc | 21 | NULL | 4192 | Using index condition; Using temporary; Using filesort |
| 1 | SIMPLE | p | ref | PRIMARY,FK4BE7532292C5D482,FK4BE75322AE503A13,FK4BE75322382D11BC,POSTING_DATE | FK4BE7532292C5D482 | 9 | smsfinance.af.ID | 54 | Using index condition; Using where |
| 1 | SIMPLE | l | eq_ref | PRIMARY | PRIMARY | 8 | smsfinance.p.loan_ID | 1 | NULL |
| 1 | SIMPLE | at | eq_ref | PRIMARY,acc | PRIMARY | 8 | smsfinance.p.toAccount_ID | 1 | Using where |
+----+-------------+-------+--------+-------------------------------------------------------------------------------+--------------------+---------+---------------------------+------+--------------------------------------------------------+
Query execute long time.
I suspect compression leads to different statistics, which can lead to different execution plans.
I see no use for the table Loan in this query. Removing it from the query may force the explain plans to be the same.
You have 200M rows in each table? Another speedup would be to shrink the tables.
Change BIGINT (8 bytes each) to INT UNSIGNED (4 bytes, range 0..4 billion) wherever possible.
Normalize the _type columns, replacing with SMALLINT UNSIGNED (2 bytes, range 0..64K) or other suitable integer type. Or turn the column into an ENUM if there are a finite, small number, of "types".
Does Account have INDEX(acc_type)? (Or at least starting with acc_type.)
Remove INNER JOIN Loan AS l ON p.loan_id = l.ID and replace l.client_ID AS 'client_ID', with
( SELECT client_ID FROM Loans WHERE ID = p.loan_id ) AS 'client_ID',
I think this will force a different query plan, perhaps a good one.

mariadb losing primary key on update

One of my tables is losing the primary key every time I make an update on that particular table.
Describe zizi_card_household
gives me this result after the update.
+-------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | | NULL | auto_increment |
| householdnumber | varchar(45) | NO | | | |
| cardnumber | varchar(45) | YES | MUL | NULL | |
| startdate | datetime | YES | | NULL | |
| enddate | datetime | YES | | NULL | |
| assignedby | int(11) | YES | | NULL | |
| assigneddate | datetime | YES | | NULL | |
Where it should normally be
+-------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| householdnumber | varchar(45) | NO | MUL | | |
| cardnumber | varchar(45) | YES | MUL | NULL | |
| startdate | datetime | YES | | NULL | |
| enddate | datetime | YES | | NULL | |
| assignedby | int(11) | YES | | NULL | |
SHOW CREATE TABLE
will give this statement which shows a primary key was defined. It's possible that entry is updated whenever the table is altered so it shows the table as it was last altered or created.
CREATE TABLE `zizi_card_household` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`householdnumber` varchar(45) NOT NULL DEFAULT '',
`cardnumber` varchar(45) DEFAULT NULL,
`startdate` datetime DEFAULT NULL,
`enddate` datetime DEFAULT NULL,
`assignedby` int(11) DEFAULT NULL,
`assigneddate` datetime DEFAULT NULL,
`deassignedby` int(11) DEFAULT NULL,
.
.
.
.
`modifiedby` int(11) DEFAULT NULL,
`reprintstatus` tinyint(4) DEFAULT NULL,
`printeddate` datetime DEFAULT NULL,
`printedby` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_householdnumber` (`householdnumber`),
KEY `idx_cardnumber` (`cardnumber`),
KEY `idx_deassignedby` (`deassignedby`),
.
.
.
.
KEY `idx_reprintstatus` (`reprintstatus`)
) ENGINE=InnoDB AUTO_INCREMENT=860137 DEFAULT CHARSET=latin1
Attempting to add a primary key
ALTER TABLE `labour`.`zizi_card_household`
CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY
at this point gives me
ERROR 1068 (42000): Multiple primary key defined
Repair table
repair table zizi_card_household;
Gives me this but it does solve the problem. The primary key returns but will get ruined the next time the table is updated.
+----------------------------+--------+----------+---------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+----------------------------+--------+----------+---------------------------------------------------------+
| labour.zizi_card_household | repair | note | The storage engine for the table doesn't support repair |
+----------------------------+--------+----------+---------------------------------------------------------+
The table and other tables have a trigger that updates a summary table. It deletes related rows and reconstructs them. It does something like
FOR EACH ROW
begin
delete from zizi_card_summary where householdnumber=new.householdnumber;
insert into zizi_card_summary(
cardnumber,cardhouseholdid,householdnumber,startdate,enddate,assignedby
.
.
.
)
select ch.cardnumber,ch.id,b.householdnumber,
ch.startdate,ch.enddate,ch.assignedby,
.
.
.
.
where b.householdnumber=new.householdnumber and b.beneficiary_type=0;
end
All other tables work just fine. Thanks. Been playing around with this for a week. The application is a Zend framework 1.12.
The db version is 10.1.11-MariaDB-log. The operating system is Linux 2.6.32-573.8.1.el6.x86_64 x86_64.
I can confirm the bug and the workaround as described by Timothy : removing the trigger keeps the Primary key after a record update.
Bug resolution progress is on https://jira.mariadb.org/browse/MDEV-9558