catfan / Medoo

The lightweight PHP database framework to accelerate the development.
https://medoo.in
MIT License
4.84k stars 1.15k forks source link

Why use named placeholders when you can use anonymous? #613

Closed Andrews54757 closed 3 years ago

Andrews54757 commented 7 years ago

https://github.com/catfan/Medoo/blob/master/src/Medoo.php#L351.

Why use named placeholders (EG SELECT * FROM `table` WHERE `arg` = :placeholder) instead of anonymous ones? (SELECT * FROM `table` WHERE `arg` = ?)

The guid is being incremented anyway. I think it would be best practice to use unnamed placeholders for clarity and performance, as well as compactness.

I think there needs to be fixes to bottlenecks such as this. With a site with large traffic, the server can have trouble.

Someone fancy for a PR?

Yousha commented 7 years ago

"anonymous" ? what's that? You meant "positional parameter" ?

And the difference between positional parameter(?) and named parameters(:) is that named parameters are a bit advanced, they don't have to be bound in order they appear. You can also repeat one named parameter multiple times in the statement, but you can bind it only once to pass the value. ^ this also leads you to write less code!

Also in positional parameter(?) you'll have to take care about the order in which they will be bound to the query.

This issue must be closed.

Andrews54757 commented 7 years ago

@Yousha Positional parameters do not have to be bound in order.

http://php.net/manual/en/pdostatement.bindparam.php

Also, medoo doesnt use that feature of binding multiple times.

Medoo instead generates a unique name using https://github.com/catfan/Medoo/blob/master/src/Medoo.php#L351.

If it is gonna increment guid anyway, then why not use positional parameters? Positional parameters tend to be faster, and it would make the code more compact.

catfan commented 7 years ago

@Andrews54757 I benchmarked (10000 times, with 5 placeholders in one query) the performance of positional parameter (14.7s ~ 14.9s) and named parameters (14.9s ~ 15.2s). There is no great performance difference between them. The positional parameter is only a little little bit faster.

The reason why we took named parameters is we need to maintain the key name and value type for the statement, and better for output the executed query for debug() and log().

The pull request #617 is made a bug for this. For example, this will error when the input value contained with question mark. Confusing.

$data = $database->debug()->select('account', [
    'user_name',
    'user_id'
], [
    'user_name' => 'foo?',
    'email' => 'bar?'
]);

// SELECT "user_name","user_id" FROM "account" WHERE "user_name" = 'foo'bar?'' AND "email" = ?

So, we have no plan and didn't see any great advanced to change it as positional parameter.

But this issue is open to discuss the benefit between this two ways.

Andrews54757 commented 7 years ago

@catfan I see, however, that can be solved very quickly. I think positional placeholders are better for clarity though, the mapKey function is confusing and ugly. But, I am fine with named parameters, I mean, it works.