GithubHelp home page GithubHelp logo

Add Hint Index in queries about db HOT 37 OPEN

yiisoft avatar yiisoft commented on May 24, 2024
Add Hint Index in queries

from db.

Comments (37)

xepozz avatar xepozz commented on May 24, 2024 1

Up

from db.

cebe avatar cebe commented on May 24, 2024

As far as I see this is already possible with existing methods. no need to add anything:

// your first example:
$query = (new Query)->from([new Expression('{{%user}} USE INDEX (primary)')]);
// your second example
$query = (new Query)
       ->from([new Expression('`user` `t` FORCE INDEX (primary) IGNORE INDEX FOR ORDER BY (i1)')])
       ->leftJoin(['p' => 'profile'], 'user.id = profile.user_id USE INDEX (i2)');

from db.

cebe avatar cebe commented on May 24, 2024

Added a test to verify this works.

from db.

fdezmc avatar fdezmc commented on May 24, 2024

I needed hint index with activeRecord. Thought it was not possible to set an expression on from clause with ActiveRecord, now I found the way:

$user = User::find()->from([new yii\db\Expression('{{%user}} USE INDEX (primary)')]);

but the use of Expression this way, will break the abstraction layer requiring recode if you decide to change to other db driver. Adding hintIndex method could solve this issue without loosing funtionality.

from db.

samdark avatar samdark commented on May 24, 2024

@fdezmc different DB engines are working differently with indexes so what you're forcing in MySQL to gain extra performance may be absolute performance hog when using PostgreSQL. If you're down to this level of working with DB you're already not likely to switch easily.

from db.

fdezmc avatar fdezmc commented on May 24, 2024

Absolutely, thank you very much for your comments.

from db.

juanmacias avatar juanmacias commented on May 24, 2024

Hi @samdark , as a former DBA, query optimisation is avery important part for large application development.
The Index Hinting is available in almost all database engines, is not only present in MySQL.

As a developer, you can specify the indexes you prefer in that query. The index hint can be generate to Oracle, PG, Mysql, etc... so the code will still works.

But, by the way. How many apps are developed for easy DB Engine Switch???

If you are concerned about easy switching between database, there is a lot of queries in MySQL that doesn't works in PG. Or at least, doesn't work as expected. It's imposible to make a compatible ORM without losing a lot of performance.

Adding Index Hinting, you are not breaking nothing, you are giving an option available in all databases.

from db.

samdark avatar samdark commented on May 24, 2024

But, by the way. How many apps are developed for easy DB Engine Switch???

Some. Installable products mainly: CMSes, CRMs etc.

from db.

juanmacias avatar juanmacias commented on May 24, 2024

I've migrated some apps from MySQL to PG in yii2 and there is a lot of work
to do. For example with nulls and 0.

On Thu, Jul 7, 2016 at 11:11 AM, Alexander Makarov <[email protected]

wrote:

But, by the way. How many apps are developed for easy DB Engine Switch???
Some. Installable products mainly: CMSes, CRMs etc.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/yiisoft/yii2/issues/10869#issuecomment-231024872, or mute
the thread
https://github.com/notifications/unsubscribe/AEk1ZX1OIdrdggZ1PeqydqFSx8ZkkMgvks5qTMLBgaJpZM4HbM1b
.

Juan Macias
CEO QaShops.com
659203561

from db.

samdark avatar samdark commented on May 24, 2024

Absolutely.

from db.

juanmacias avatar juanmacias commented on May 24, 2024

So, you won't approve a feature to help developers optimice the SQLs on major database, just because you want Yii2 to be compatible with all databases.

A decision that helps 1% of developers and f*cks 99% developers of large applications.

from db.

juanmacias avatar juanmacias commented on May 24, 2024

Don't mind, we have managed to extend QueryBuilder to add this feature and being compatible with Yii2.

from db.

marekpetras avatar marekpetras commented on May 24, 2024

Hey @juanmacias , mind sharing the extension?

Cheers

from db.

dynasource avatar dynasource commented on May 24, 2024

Yii2 is known for its speed. Therefore this functionality should be adopted.

from db.

dynasource avatar dynasource commented on May 24, 2024

the examples above with Expression did not seem to work. Thats confusing. However, I managed to get it working for ->from with an example like this:

        $this->from(['USE INDEX (visitor_timestamp)' => $tableName]);

Apart from this workaround, we should have this functionality in core. I don't see why this is left out. Even if 1 or 2 DB engines don't support it, should not mean it shouldnt be implemented.

People have spent many, many hours to have their architecture ready to actually benefit from these indexes. If it then seems to be useless, this is frustrating and even more worse, the difference of a page loading in 10ms or 10 seconds.

from db.

cebe avatar cebe commented on May 24, 2024

the examples above with Expression did not seem to work.

@dynasource what exactly does not work for you? There is a test that checks that it works: b9880f32474bf30bd7662ee7f3465a0e58a2be2b

from db.

dynasource avatar dynasource commented on May 24, 2024

this example did not work:

$query = (new Query)->from([new Expression('{{%user}} USE INDEX (primary)')]);

I have to recheck for the specific error

from db.

dynasource avatar dynasource commented on May 24, 2024

I think I found the issue again:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'USE INDEX (visitor_timestamp)' at line 1 The SQL being executed was: SHOW FULL COLUMNS FROM stats_normal_2016 USE INDEX (visitor_timestamp)

from db.

cebe avatar cebe commented on May 24, 2024

There must be something more specific you do for that error. The line you posted works fine: 6caedd1

from db.

fdezmc avatar fdezmc commented on May 24, 2024

As mentioned in #11807 this don´t work with joinWith.

// works!!!
$query = (new Query)->from([new Expression('{{%user}} USE INDEX (primary)')]);

// joinWith relation fails
$query = (new Query)->from([new Expression('{{%user}} USE INDEX (primary)')])
->joinWith('userProfile');

Note: userProfile is a relation between user and profile ON user.id = profile.user_id

ActiveQuery class method joinWithRelation takes as $parentAlias an expression resulting in:

SELECT * FROM user USE INDEX (primary) LEFT JOIN profile ON user USE INDEX (primary).id = profile.user_id

instead of

SELECT * FROM user USE INDEX (primary) LEFT JOIN profile ON user.id = profile.user_id

from db.

juanmacias avatar juanmacias commented on May 24, 2024

Well, I didn't want to share the code because is an horrible workaround (but works), I'm not proud of using it, but is the only way I've found.

How to use install it:

  1. Add the code to your project (I had no time to release it as a module, any volunteer? )

  2. Add in your main_local:

return [
    'components' => [
        'db' => [
            'class' => 'common\components\qamysqlconnection\Connection',

  1. In the Active Models you want to enable ForceIndex, just put this:
public static function find()
   {
    return new QaActiveQuery(get_called_class());
}

or override your Query class.

How to use it
With this, you will have a new fromOption() method in the ActiveQuery where you can specify whatever you want, like a "force Index"
Example:
Product::find()->fromOption("FORCE INDEX(supplier_reference, parent_id)")->all();

qamysqlconnection.zip

from db.

bhagwatchouhan avatar bhagwatchouhan commented on May 24, 2024

Thanks Juan for your solution.

from db.

malsatin avatar malsatin commented on May 24, 2024

Please, resolve this problem. It hurts. And as plans for 2.1.1 are dropped, this issue became dropped too

from db.

samdark avatar samdark commented on May 24, 2024

Plans aren't dropped. Versioning was adjusted, that's it.

from db.

ailiangkuai avatar ailiangkuai commented on May 24, 2024

please resolve this problem.I found that through Active Record I have no way to use force index in mysql.

from db.

malsatin avatar malsatin commented on May 24, 2024

I have prepared slight improvement over @juanmacias code
Put this folder into ./common/extensions/qaConnection

Then you can just add use QaRecordTrait; to your ActiveRecord model and use it like that

YourModel::find()
   ->tableOption('FORCE INDEX(`' . $index . '`)')
   ->...

or

YourModel::find()
   ->from(['your_model' => 'model'])
   ->tableOption(['model' => 'FORCE INDEX(`' . $index . '`)'])
   ->...

Code: qaConnection.zip

from db.

ailiangkuai avatar ailiangkuai commented on May 24, 2024

Thank you for your help! @mattrh

from db.

samdark avatar samdark commented on May 24, 2024

yiisoft/yii2#13607

from db.

julianrutten avatar julianrutten commented on May 24, 2024

Is there any way to do this? When I use the from option it overwrites all the joins as discussed above. Seems like this should be in to be honest. Can I help?

from db.

samdark avatar samdark commented on May 24, 2024

Not in Yii 2.

from db.

julianrutten avatar julianrutten commented on May 24, 2024

Shouldnt this be closed then if you have given up?

from db.

samdark avatar samdark commented on May 24, 2024

It is not Yii 2 repository.

from db.

julianrutten avatar julianrutten commented on May 24, 2024

You referenced a Yii2 issue and closed that one. I am not a mind reader sadly.

from db.

samdark avatar samdark commented on May 24, 2024

The issue was closed in Yii 2 because it won't be implemented there and created here because it makes sense to implement it in this package.

from db.

julianrutten avatar julianrutten commented on May 24, 2024

Ahhh, I missed the whole Yii3 memo. Sorry about that!

from db.

jlrtutor avatar jlrtutor commented on May 24, 2024

You can easily use FORCE INDEX in a simple way.
Just use:
$items = Author::find()->leftJoin('book AS book FORCE INDEX (fk_book_column_id)', 'author.id = book.author_id')

It generates:
SELECT * FROM author LEFT JOIN book as book FORCE INDEX (fk_book_column_id) ON author.id = book.author_id

Defining the table alias as its own name does the trick and then add the FORCE/USE INDEX statement.

from db.

EasySoftwarePoland avatar EasySoftwarePoland commented on May 24, 2024

Just to confirm @jlrtutor's message, there is a way:

$postsQuery = Post::find()
            ->select('post.*')
            ->from([new Expression('{{%post}} FORCE INDEX (indx_post_status_date)')])
            ->innerJoin('user AS user FORCE INDEX (indx_user_domain)', 'post.User_OID = user.OID')

from db.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.