Fastest method to save pageviews in database with doctrine











up vote
0
down vote

favorite












Using Symfony 4 with doctrine, I want to save pageviews for one entity Program in the database. I want to save this to the database because I want to give some users the rights to view these numbers. What I have done is add a property to the entity like this:



Program.php



/**
* @ORMColumn(type="integer", nullable=true)
*/
private $pageViews;

/**
* @return mixed
*/
public function getPageViews()
{
return $this->pageViews;
}

/**
* @param mixed $pageViews
*/
public function setPageViews($pageViews)
{
$this->pageViews = $pageViews;
}


And in my ProgramController.php in the function showProgram



//...
$program->setPageViews($program->getPageViews()+1);
$em->persist($program);
$em->flush();


This works and adds 1 to the existing number every time the page is refreshed. My question is, is this an acceptable method or are there faster/better alternatives? And does this slow down performance or is that negligible?










share|improve this question






















  • public function addPageViews() { ++$this->pageViews; } might be a bit faster, beside that, I don't see what could be optimised
    – Cid
    Nov 13 at 9:29












  • You can use doctrines dql lang, so you avoid hydrating entities, so it will be much faster, sth like this - UPDATE MyProjectModelProgram p SET p.pageViews = p.pageViews + 1
    – Eakethet
    Nov 13 at 9:44

















up vote
0
down vote

favorite












Using Symfony 4 with doctrine, I want to save pageviews for one entity Program in the database. I want to save this to the database because I want to give some users the rights to view these numbers. What I have done is add a property to the entity like this:



Program.php



/**
* @ORMColumn(type="integer", nullable=true)
*/
private $pageViews;

/**
* @return mixed
*/
public function getPageViews()
{
return $this->pageViews;
}

/**
* @param mixed $pageViews
*/
public function setPageViews($pageViews)
{
$this->pageViews = $pageViews;
}


And in my ProgramController.php in the function showProgram



//...
$program->setPageViews($program->getPageViews()+1);
$em->persist($program);
$em->flush();


This works and adds 1 to the existing number every time the page is refreshed. My question is, is this an acceptable method or are there faster/better alternatives? And does this slow down performance or is that negligible?










share|improve this question






















  • public function addPageViews() { ++$this->pageViews; } might be a bit faster, beside that, I don't see what could be optimised
    – Cid
    Nov 13 at 9:29












  • You can use doctrines dql lang, so you avoid hydrating entities, so it will be much faster, sth like this - UPDATE MyProjectModelProgram p SET p.pageViews = p.pageViews + 1
    – Eakethet
    Nov 13 at 9:44















up vote
0
down vote

favorite









up vote
0
down vote

favorite











Using Symfony 4 with doctrine, I want to save pageviews for one entity Program in the database. I want to save this to the database because I want to give some users the rights to view these numbers. What I have done is add a property to the entity like this:



Program.php



/**
* @ORMColumn(type="integer", nullable=true)
*/
private $pageViews;

/**
* @return mixed
*/
public function getPageViews()
{
return $this->pageViews;
}

/**
* @param mixed $pageViews
*/
public function setPageViews($pageViews)
{
$this->pageViews = $pageViews;
}


And in my ProgramController.php in the function showProgram



//...
$program->setPageViews($program->getPageViews()+1);
$em->persist($program);
$em->flush();


This works and adds 1 to the existing number every time the page is refreshed. My question is, is this an acceptable method or are there faster/better alternatives? And does this slow down performance or is that negligible?










share|improve this question













Using Symfony 4 with doctrine, I want to save pageviews for one entity Program in the database. I want to save this to the database because I want to give some users the rights to view these numbers. What I have done is add a property to the entity like this:



Program.php



/**
* @ORMColumn(type="integer", nullable=true)
*/
private $pageViews;

/**
* @return mixed
*/
public function getPageViews()
{
return $this->pageViews;
}

/**
* @param mixed $pageViews
*/
public function setPageViews($pageViews)
{
$this->pageViews = $pageViews;
}


And in my ProgramController.php in the function showProgram



//...
$program->setPageViews($program->getPageViews()+1);
$em->persist($program);
$em->flush();


This works and adds 1 to the existing number every time the page is refreshed. My question is, is this an acceptable method or are there faster/better alternatives? And does this slow down performance or is that negligible?







php symfony doctrine2






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 13 at 9:19









Dirk J. Faber

9881217




9881217












  • public function addPageViews() { ++$this->pageViews; } might be a bit faster, beside that, I don't see what could be optimised
    – Cid
    Nov 13 at 9:29












  • You can use doctrines dql lang, so you avoid hydrating entities, so it will be much faster, sth like this - UPDATE MyProjectModelProgram p SET p.pageViews = p.pageViews + 1
    – Eakethet
    Nov 13 at 9:44




















  • public function addPageViews() { ++$this->pageViews; } might be a bit faster, beside that, I don't see what could be optimised
    – Cid
    Nov 13 at 9:29












  • You can use doctrines dql lang, so you avoid hydrating entities, so it will be much faster, sth like this - UPDATE MyProjectModelProgram p SET p.pageViews = p.pageViews + 1
    – Eakethet
    Nov 13 at 9:44


















public function addPageViews() { ++$this->pageViews; } might be a bit faster, beside that, I don't see what could be optimised
– Cid
Nov 13 at 9:29






public function addPageViews() { ++$this->pageViews; } might be a bit faster, beside that, I don't see what could be optimised
– Cid
Nov 13 at 9:29














You can use doctrines dql lang, so you avoid hydrating entities, so it will be much faster, sth like this - UPDATE MyProjectModelProgram p SET p.pageViews = p.pageViews + 1
– Eakethet
Nov 13 at 9:44






You can use doctrines dql lang, so you avoid hydrating entities, so it will be much faster, sth like this - UPDATE MyProjectModelProgram p SET p.pageViews = p.pageViews + 1
– Eakethet
Nov 13 at 9:44














1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










Since you don't really need the entity you could directly do this with SQL, using Doctrine's connection:



$connection = $this->getDoctrine()->getConnection();
$connection->executeUpdate('UPDATE page_view_counter SET page_view = page_view+1;');


or using a preprared statement:



$connection = $this->getDoctrine()->getConnection();
$statement = $connection->prepare(
'UPDATE programs SET page_views = page_views + 1 WHERE programs.id = :id'
);
$statement->bindValue('id', $id);
$statement->execute();


This would speed up things a bit by not using some of the more complex features of the ORM that you don't need for your case.



Another alternative for speeding things up could be to switch technologies, like storing the data in a cache like redis. Whether this will actually improve performance (especially under a heavier load) would need to be verified using some measuring tool like JMeter.






share|improve this answer























  • I do need the entity, because on the page I show I need to show program variables. So I guess in that case my or Cid's solution might be better?
    – Dirk J. Faber
    Nov 13 at 14:33










  • Yes, for the beginning at least. You still have to be careful as your code might produce race conditions. If user A & B load the site at roughly the same time, let's say 100 page_views, they will both load this value and increment that. Then they will save their value and therefore no matter which of both saves the value last, the counter will probably say 101, instead of 102. With my code, this will not happen because each query updates the value in the database directly instead of loading it first. If you don't mind the chance for this slight variance your solution should work just fine.
    – dbrumann
    Nov 13 at 16:26






  • 1




    Cid's approach will have the same drawback by the way. As it also loads the value into the entity, updates it and then saves the new entity state to the database. The only way to get around it, is to make the update atomic, by not retrieving it first, but instead doing the +1 directly in the database using SQL.
    – dbrumann
    Nov 13 at 16:27










  • Obviously, directly sending SQL query is certainly the best option. This query is simple enough to avoid coupling issues bewteen differents DBMS. Let's hope you don't have fields and table badly named that requires to be wrapped into backticks or brackets
    – Cid
    Nov 14 at 7:53








  • 1




    Yes, DBAL also supports parameters: doctrine-project.org/projects/doctrine-dbal/en/2.8/reference/…. I have added an example to my answer
    – dbrumann
    Nov 14 at 15:11













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53277593%2ffastest-method-to-save-pageviews-in-database-with-doctrine%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










Since you don't really need the entity you could directly do this with SQL, using Doctrine's connection:



$connection = $this->getDoctrine()->getConnection();
$connection->executeUpdate('UPDATE page_view_counter SET page_view = page_view+1;');


or using a preprared statement:



$connection = $this->getDoctrine()->getConnection();
$statement = $connection->prepare(
'UPDATE programs SET page_views = page_views + 1 WHERE programs.id = :id'
);
$statement->bindValue('id', $id);
$statement->execute();


This would speed up things a bit by not using some of the more complex features of the ORM that you don't need for your case.



Another alternative for speeding things up could be to switch technologies, like storing the data in a cache like redis. Whether this will actually improve performance (especially under a heavier load) would need to be verified using some measuring tool like JMeter.






share|improve this answer























  • I do need the entity, because on the page I show I need to show program variables. So I guess in that case my or Cid's solution might be better?
    – Dirk J. Faber
    Nov 13 at 14:33










  • Yes, for the beginning at least. You still have to be careful as your code might produce race conditions. If user A & B load the site at roughly the same time, let's say 100 page_views, they will both load this value and increment that. Then they will save their value and therefore no matter which of both saves the value last, the counter will probably say 101, instead of 102. With my code, this will not happen because each query updates the value in the database directly instead of loading it first. If you don't mind the chance for this slight variance your solution should work just fine.
    – dbrumann
    Nov 13 at 16:26






  • 1




    Cid's approach will have the same drawback by the way. As it also loads the value into the entity, updates it and then saves the new entity state to the database. The only way to get around it, is to make the update atomic, by not retrieving it first, but instead doing the +1 directly in the database using SQL.
    – dbrumann
    Nov 13 at 16:27










  • Obviously, directly sending SQL query is certainly the best option. This query is simple enough to avoid coupling issues bewteen differents DBMS. Let's hope you don't have fields and table badly named that requires to be wrapped into backticks or brackets
    – Cid
    Nov 14 at 7:53








  • 1




    Yes, DBAL also supports parameters: doctrine-project.org/projects/doctrine-dbal/en/2.8/reference/…. I have added an example to my answer
    – dbrumann
    Nov 14 at 15:11

















up vote
2
down vote



accepted










Since you don't really need the entity you could directly do this with SQL, using Doctrine's connection:



$connection = $this->getDoctrine()->getConnection();
$connection->executeUpdate('UPDATE page_view_counter SET page_view = page_view+1;');


or using a preprared statement:



$connection = $this->getDoctrine()->getConnection();
$statement = $connection->prepare(
'UPDATE programs SET page_views = page_views + 1 WHERE programs.id = :id'
);
$statement->bindValue('id', $id);
$statement->execute();


This would speed up things a bit by not using some of the more complex features of the ORM that you don't need for your case.



Another alternative for speeding things up could be to switch technologies, like storing the data in a cache like redis. Whether this will actually improve performance (especially under a heavier load) would need to be verified using some measuring tool like JMeter.






share|improve this answer























  • I do need the entity, because on the page I show I need to show program variables. So I guess in that case my or Cid's solution might be better?
    – Dirk J. Faber
    Nov 13 at 14:33










  • Yes, for the beginning at least. You still have to be careful as your code might produce race conditions. If user A & B load the site at roughly the same time, let's say 100 page_views, they will both load this value and increment that. Then they will save their value and therefore no matter which of both saves the value last, the counter will probably say 101, instead of 102. With my code, this will not happen because each query updates the value in the database directly instead of loading it first. If you don't mind the chance for this slight variance your solution should work just fine.
    – dbrumann
    Nov 13 at 16:26






  • 1




    Cid's approach will have the same drawback by the way. As it also loads the value into the entity, updates it and then saves the new entity state to the database. The only way to get around it, is to make the update atomic, by not retrieving it first, but instead doing the +1 directly in the database using SQL.
    – dbrumann
    Nov 13 at 16:27










  • Obviously, directly sending SQL query is certainly the best option. This query is simple enough to avoid coupling issues bewteen differents DBMS. Let's hope you don't have fields and table badly named that requires to be wrapped into backticks or brackets
    – Cid
    Nov 14 at 7:53








  • 1




    Yes, DBAL also supports parameters: doctrine-project.org/projects/doctrine-dbal/en/2.8/reference/…. I have added an example to my answer
    – dbrumann
    Nov 14 at 15:11















up vote
2
down vote



accepted







up vote
2
down vote



accepted






Since you don't really need the entity you could directly do this with SQL, using Doctrine's connection:



$connection = $this->getDoctrine()->getConnection();
$connection->executeUpdate('UPDATE page_view_counter SET page_view = page_view+1;');


or using a preprared statement:



$connection = $this->getDoctrine()->getConnection();
$statement = $connection->prepare(
'UPDATE programs SET page_views = page_views + 1 WHERE programs.id = :id'
);
$statement->bindValue('id', $id);
$statement->execute();


This would speed up things a bit by not using some of the more complex features of the ORM that you don't need for your case.



Another alternative for speeding things up could be to switch technologies, like storing the data in a cache like redis. Whether this will actually improve performance (especially under a heavier load) would need to be verified using some measuring tool like JMeter.






share|improve this answer














Since you don't really need the entity you could directly do this with SQL, using Doctrine's connection:



$connection = $this->getDoctrine()->getConnection();
$connection->executeUpdate('UPDATE page_view_counter SET page_view = page_view+1;');


or using a preprared statement:



$connection = $this->getDoctrine()->getConnection();
$statement = $connection->prepare(
'UPDATE programs SET page_views = page_views + 1 WHERE programs.id = :id'
);
$statement->bindValue('id', $id);
$statement->execute();


This would speed up things a bit by not using some of the more complex features of the ORM that you don't need for your case.



Another alternative for speeding things up could be to switch technologies, like storing the data in a cache like redis. Whether this will actually improve performance (especially under a heavier load) would need to be verified using some measuring tool like JMeter.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 14 at 15:14

























answered Nov 13 at 11:14









dbrumann

9,11111940




9,11111940












  • I do need the entity, because on the page I show I need to show program variables. So I guess in that case my or Cid's solution might be better?
    – Dirk J. Faber
    Nov 13 at 14:33










  • Yes, for the beginning at least. You still have to be careful as your code might produce race conditions. If user A & B load the site at roughly the same time, let's say 100 page_views, they will both load this value and increment that. Then they will save their value and therefore no matter which of both saves the value last, the counter will probably say 101, instead of 102. With my code, this will not happen because each query updates the value in the database directly instead of loading it first. If you don't mind the chance for this slight variance your solution should work just fine.
    – dbrumann
    Nov 13 at 16:26






  • 1




    Cid's approach will have the same drawback by the way. As it also loads the value into the entity, updates it and then saves the new entity state to the database. The only way to get around it, is to make the update atomic, by not retrieving it first, but instead doing the +1 directly in the database using SQL.
    – dbrumann
    Nov 13 at 16:27










  • Obviously, directly sending SQL query is certainly the best option. This query is simple enough to avoid coupling issues bewteen differents DBMS. Let's hope you don't have fields and table badly named that requires to be wrapped into backticks or brackets
    – Cid
    Nov 14 at 7:53








  • 1




    Yes, DBAL also supports parameters: doctrine-project.org/projects/doctrine-dbal/en/2.8/reference/…. I have added an example to my answer
    – dbrumann
    Nov 14 at 15:11




















  • I do need the entity, because on the page I show I need to show program variables. So I guess in that case my or Cid's solution might be better?
    – Dirk J. Faber
    Nov 13 at 14:33










  • Yes, for the beginning at least. You still have to be careful as your code might produce race conditions. If user A & B load the site at roughly the same time, let's say 100 page_views, they will both load this value and increment that. Then they will save their value and therefore no matter which of both saves the value last, the counter will probably say 101, instead of 102. With my code, this will not happen because each query updates the value in the database directly instead of loading it first. If you don't mind the chance for this slight variance your solution should work just fine.
    – dbrumann
    Nov 13 at 16:26






  • 1




    Cid's approach will have the same drawback by the way. As it also loads the value into the entity, updates it and then saves the new entity state to the database. The only way to get around it, is to make the update atomic, by not retrieving it first, but instead doing the +1 directly in the database using SQL.
    – dbrumann
    Nov 13 at 16:27










  • Obviously, directly sending SQL query is certainly the best option. This query is simple enough to avoid coupling issues bewteen differents DBMS. Let's hope you don't have fields and table badly named that requires to be wrapped into backticks or brackets
    – Cid
    Nov 14 at 7:53








  • 1




    Yes, DBAL also supports parameters: doctrine-project.org/projects/doctrine-dbal/en/2.8/reference/…. I have added an example to my answer
    – dbrumann
    Nov 14 at 15:11


















I do need the entity, because on the page I show I need to show program variables. So I guess in that case my or Cid's solution might be better?
– Dirk J. Faber
Nov 13 at 14:33




I do need the entity, because on the page I show I need to show program variables. So I guess in that case my or Cid's solution might be better?
– Dirk J. Faber
Nov 13 at 14:33












Yes, for the beginning at least. You still have to be careful as your code might produce race conditions. If user A & B load the site at roughly the same time, let's say 100 page_views, they will both load this value and increment that. Then they will save their value and therefore no matter which of both saves the value last, the counter will probably say 101, instead of 102. With my code, this will not happen because each query updates the value in the database directly instead of loading it first. If you don't mind the chance for this slight variance your solution should work just fine.
– dbrumann
Nov 13 at 16:26




Yes, for the beginning at least. You still have to be careful as your code might produce race conditions. If user A & B load the site at roughly the same time, let's say 100 page_views, they will both load this value and increment that. Then they will save their value and therefore no matter which of both saves the value last, the counter will probably say 101, instead of 102. With my code, this will not happen because each query updates the value in the database directly instead of loading it first. If you don't mind the chance for this slight variance your solution should work just fine.
– dbrumann
Nov 13 at 16:26




1




1




Cid's approach will have the same drawback by the way. As it also loads the value into the entity, updates it and then saves the new entity state to the database. The only way to get around it, is to make the update atomic, by not retrieving it first, but instead doing the +1 directly in the database using SQL.
– dbrumann
Nov 13 at 16:27




Cid's approach will have the same drawback by the way. As it also loads the value into the entity, updates it and then saves the new entity state to the database. The only way to get around it, is to make the update atomic, by not retrieving it first, but instead doing the +1 directly in the database using SQL.
– dbrumann
Nov 13 at 16:27












Obviously, directly sending SQL query is certainly the best option. This query is simple enough to avoid coupling issues bewteen differents DBMS. Let's hope you don't have fields and table badly named that requires to be wrapped into backticks or brackets
– Cid
Nov 14 at 7:53






Obviously, directly sending SQL query is certainly the best option. This query is simple enough to avoid coupling issues bewteen differents DBMS. Let's hope you don't have fields and table badly named that requires to be wrapped into backticks or brackets
– Cid
Nov 14 at 7:53






1




1




Yes, DBAL also supports parameters: doctrine-project.org/projects/doctrine-dbal/en/2.8/reference/…. I have added an example to my answer
– dbrumann
Nov 14 at 15:11






Yes, DBAL also supports parameters: doctrine-project.org/projects/doctrine-dbal/en/2.8/reference/…. I have added an example to my answer
– dbrumann
Nov 14 at 15:11




















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53277593%2ffastest-method-to-save-pageviews-in-database-with-doctrine%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

ComboBox Display Member on multiple fields

Is it possible to collect Nectar points via Trainline?