-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[RFC] Another way to fast reorder table with single SQL query #12839
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
so, for what i understand this will work on all database drivers, except SQLLite |
libraries/joomla/table/table.php
Outdated
| $k = $this->_tbl_key; | ||
| $subquery = $this->_db->getQuery(true) | ||
| ->from($this->_tbl) | ||
| ->windowRowNumber('ordering', 'new_ordering'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not related to the PR itself, but shouldn't $this->getColumnAlias('ordering') be used to allow more flexibility when naming the table columns?
See #12464
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will take a look.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with that but should I use that before it will be merged?
|
There is missing a few unit tests for windowRowNumber but you can start testing. |
|
ok will try to test today or tomorrow, but as said i can only test mysql. |
|
I have found one issue with |
JTable::reorder() does not need to call it more than once, right ? Example of some query that will be created if it is called twice SELECT *
FROM
(
SELECT lang.lang_code
,(SELECT @a := @a + 1 FROM (SELECT @a := 0) AS row_init) as num1
,(SELECT @a := @a + 1 FROM (SELECT @a := 0) AS row_init) as num2
FROM #__languages AS lang
ORDER_BY _window_order_
)
AS window
ORDER BY _order_
maybe it is best to throw an exception if someone tries to call it multiple times (throw because it is not implemented / supported thus prevent wrong usage of it, and no B/C issue, since the method is new)
|
I tried to implement some code but I'm back to the same conclusion. I will add |
|
It is nice to see some PRs in this repository that try to squeeze some extra performance out some code but this PR does not try to squeeze a little extra performance out of something that causes unacceptable performance and race conditions in large websites, when saving articles and when reordering articles and large menus Also this PR involved some hard work and considerable time by @csthomas to add code and test all DBs, (even support MSSQL that currently noone uses), when no-one else would spend time to do a proper job (for all DBs) for years and this PR achieves a 50x-100x speedup of JTable reorder in large websites (and is much more complete work for MySQL too, unlike previous PRs) even my similar purpose PR #11184 , that involved quite some time by me, i will be very happy to close after / if this PR gets enough testing to be merged
Author has also tested on MSSQL, and i almost did too, but i run into some problems installing and configuring SQL server, that delayed me, but i will find time to do it in the short term future to test MSQL too I hope more people, can put this PR in their "testing / contributing list" e.g. @alikon @csthomas, can you check and fix the conflicts ? |
|
Fixed but the last issue is still PostgreSQL version from It has to be at least 8.4.0. |
|
There isn't an acceptable way to raise the minimum supported database engine version and block upgrades on an unsupported environment in any current stable release (somewhere there's a PR to add this support because it will be a requirement for 4.0 but it is definitely not in 3.6.5), so from that aspect you're out of luck trying to raise the minimum. From a practical perspective, you might get lucky though. There are no PostgreSQL 8.3 installs in the stats server and the oldest reported install uses 8.4.2. |
|
Is it worth more to work on this? If not then I will close that PR. |
If there are a couple of persons using a previous postgreSQL version, then they can upgrade, There has been a lot of testing of many PR that were doing almost nothing, The car is runs ok, but it is burning oil, and we care more for polishing it ? Can this PR get a high priority label (i guess critical would be for a security issue) |
|
I have updated PR. PR need to be tested again. |
|
I ll re-test during week |
Not for 3.x. However, it might be a candidate for Joomla!4.0, so the PR should be made against 4.0-dev instead of staging. |
Stopping this PR for 1 or 2 non-existing postgreSQL user of 8.3.NN is acceptable ? while saving an article in a category with 1,000 articles or if you have 5,000 articles, Race conditions in DB updating when re-ordering large menu is acceptable ? (this PR minimizes them) People having to hack the JTable reorder (using PR(s) proposed here or not proposed here) to make it usable in large websites is acceptable ? There were other changes made in J3.4 J3.5 J3.6 that broke unintentionally several sites and this change will not even break any 8.3.NN postgreSQL sites because they don't exist, or if it is possible (because of the way upgrade is done) |
|
Is there an option to check what version of postgreSQL is running and use a workaround for that? |
|
I don't think we can check the db version for the update. We only have checks in place for the PHP version. We added those since we had that B/C break due to a serious security issue where we raised the PHP minimum to 5.3.10.
Either back that statement with facts or don't use such a statement when you want to break peoples sites. Semantic versioning is very clear about this question. You can't do it in 3.x. You can do it for 4.0. |
|
We use Semantic Versioning, so BC break within the 3.x series is not acceptable. To get this improvement into 3,x, it will need a version switch providing the improvement for 8.4+, and keeping the old behaviour for pgsql < 8.4. There is no other option. |
|
would be great to have it for 3.x but rules are rules and there is not other way as to make this change against the 4.0 branch |
|
FWIW, the general argument outside the Joomla community is that semantic versioning only applies to the exposed API; it does NOT apply to the minimum supported version of a dependency (otherwise one could argue our updates of third party libraries are backward compatibility breaks as we in many cases also make changes which take advantage of the new version's features or have bumped a minimum dependency to ensure packages which weren't PHP 7 compatible weren't installed or to block packages with security vulnerabilities). While raising a minimum for more visible things like PHP and database versions is usually more painful than raising the minimum for the Registry or PHPMailer packages, the act of raising a minimum in and of itself is generally not a B/C break. There is also a practical argument to be made here, given by this screenshot: There are ZERO reported PostgreSQL 8.3 users in our statistics database. This may not be a 100% accurate statement due to the optional nature of sending the data, but this argument is now hitting a point where there's a practical side (nobody is using it, at least per the data the project has been collecting for a year now) and a procedural side. As pointed out, until #12355 is in production (so 3.7) there isn't a way to check and block the upgrade if it were decided to allow it. So that does make it harder to just say yes. |
|
imho we are still missing the main point: |
|
Without changing the way the data is stored and processed (which would be a more painful B/C break to deal with), what can you do about that? |
|
JTable::reorder should never use 1 SQL query per updated row, regardless of where it is called
but after this PR is accepted, updating a category with 10,000 records will be have JTable::reorder() cost of e.g. 1 second instead of 120seconds - 200 seconds, finally code added by this PR , i suspect will be useful in other places too ! |
|
Thanks for all comments. This PR won't go to 3.7. I want to create another PR with less functionality (without partition) that won't require newer postgreSQL. Example: -- Added on create connection
CREATE TEMP SEQUENCE rn;
-- On queries
SELECT *, nextval('rn') - 1 AS rn FROM (SELECT id, title FROM #__content LIMIT 10 OFFSET 2) AS a, (SELECT setval('rn', 1)) AS x; |
|
I close this PR. Please test a new version at #13505 |

Pull Request for Issue #10567.
Related PRs #11184 and #8563
Summary of Changes
JTablereordermethod.JDatabaseQueryselectRowNumber()with support for mysql, postgresql>=8.4, sqlsrv and sqlite3.UPDATEsyntax to reorder table in one sql query.(string) $query;returned different result.INSERT OR REPLACE INTOROW_NUMBER(init=null, partitionBy=null)after establish a connection.Testing Instructions
Just as in a competitive PR #11184.
In short:
Note:
The test to be more enjoyable, you can add below code after
$query->execute()https://github.com/joomla/joomla-cms/pull/12839/files#diff-8254e2c441a41d3fa26f0f83fbbb3043R1390
Documentation Changes Required
Probably.
Introduce a new public method
JDatabaseQuery::selectRowNumber().Main database drivers (mysql, postgresql, sqlsrv and sqlite) can use Update with innerJoin.
SQLite driver has a new sqlite function
ROW_NUMBER(init=null, partitionBy=null)