Skip to content

Drop the unused id_country index on address when upgrading - #1888

Open
boo-code wants to merge 1 commit into
PrestaShop:devfrom
boo-code:fix/drop-address-country-index
Open

Drop the unused id_country index on address when upgrading#1888
boo-code wants to merge 1 commit into
PrestaShop:devfrom
boo-code:fix/drop-address-country-index

Conversation

@boo-code

Copy link
Copy Markdown

Companion to PrestaShop/PrestaShop#42162, which removes the id_country index on address from the install schema. That side only changes new shops - existing ones keep the index, and they are the ones with enough orders to feel it.

Why the index goes

It has no reader. Every core reference to address.id_country is a join against country that resolves through country.PRIMARY - Customer.php twice, CustomerAddressQueryBuilder, AddressQueryBuilder, and OrderCountriesChoiceProvider where the equality is against country_lang. No core query filters address by a literal country, and there is no foreign key on it.

What it does do is mislead the optimizer on the orders grid. Measured on a development shop with 60 005 orders and 45 006 addresses, running the join shape that grid builds:

median of 3 plan
with id_country 152 ms drives country_lang (ALL), then country, then address via id_country, Using temporary; Using filesort
without it 45 ms drives orders on PRIMARY, rows=50, backward index scan, no filesort

PrestaShop/PrestaShop#41291 reports 4.7 s against 1.3 ms on 540k orders, which is the same plan flip at a larger scale.

Why a PHP callback and not a plain ALTER

9.0.1.sql drops an index directly, so the bare statement would match precedent. It is the wrong shape here: the workaround circulating for #41291 is to run

ALTER TABLE `ps_address` DROP INDEX `id_country`;

by hand, so on exactly the shops that were hurting the index is already gone, and DROP INDEX on a missing index is an error. MySQL has no IF EXISTS for indexes and DROP INDEX IF EXISTS is MariaDB only, so the check has to happen before the statement. The callback returns true when there is nothing to drop.

Version file

9.1.5.sql, matching the branch #42162 targets. If that PR is retargeted, this should move with it - say so and I will rename the file.

What I could not run

The module's .php-cs-fixer.dist.php loads a ruleset from the module's own vendor/, which I do not have installed, so I did not run it and am not claiming a pass. The file follows the shape of the existing callbacks - same header, same DbWrapper import, same signature style. php -l is clean.

Companion to PrestaShop/PrestaShop#42162, which removes the index from the
install schema. Existing shops keep it until it is dropped for them, and it
is the one that misleads the optimizer on the orders grid.

Guarded through a PHP callback rather than a bare ALTER: shops that already
dropped it by hand would otherwise fail the upgrade, and MySQL has no
IF EXISTS for indexes.
@ps-jarvis

Copy link
Copy Markdown
Collaborator

Hello @boo-code!

This is your first pull request on autoupgrade repository of the PrestaShop project.

Thank you, and welcome to this Open Source community!

@sonarqubecloud

Copy link
Copy Markdown

@Quetzacoalt91 Quetzacoalt91 added the Blocked Status: The issue is blocked by another task label Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Blocked Status: The issue is blocked by another task Migration script

Projects

Status: Ready for review

Development

Successfully merging this pull request may close these issues.

3 participants