Method in EncounterService is causing extreme slowness in production

We recently upgraded from OpenMRS 1.12 to OpenMRS 2.0.6.

The EncounterService.getEncountersByPatientIdentifier() is extremely slow and at times unusable in our production environment. We are attempting to search for encounters using the patient identifier. Below is an example of how we are using it:

String mrn = “exampleMRN1234”; EncounterService encounterService = Context.getEncounterService(); List encounters = encounterService.getEncountersByPatientIdentifier(mrn);

This method takes approximately 20 seconds to return a result. In our previous version of OpenMRS this method worked just fine.

For troubleshooting purposes, is it any better with platform 2.1.2?

That is incase this has some improvements https://issues.openmrs.org/browse/TRUNK-425

I don’t currently have a way to test this against 2.1.2. Our production environment is not setup to run against 2.1.2 and I cannot move PHI to our test environment. I’m assuming this happens because the patient search that is used in this method looks at more than just identifier tables to match a patient. It also looks at the person_attribute table.

@david5780 are you in a position to do any profiling? E.g. to try running against a deidentified copy of your database using a profiler? Or alternately to just put in some breakpoints or println statements in the code and determine what part of this method is slow?

Also, how many results are you typically having returned in these cases?

I can try to dig into this a bit more on our test database. The cases I’ve tested so far have only returned 1 result, which we expect because we only intend to search by identifier. Just some general thoughts on this method. The name is getEncountersByPatientIdentifier(). However, this goes out and searches by a bunch of other criteria. Based on the name of the method, it shouldn’t do that.

@david5780 in regards to looking at the person_attribute table, do you mean this? https://issues.openmrs.org/browse/TRUNK-2472

I’m not sure specifically which part of the search is slow. I’m still looking into this on our test server. What I’m trying to point out here is that this method searches more criteria other than just patient identifier, which is not what the name of the method implies. We intend to find one match for the patient using the patient identifier and no other search criteria. The identifier we are searching with would be unique. Looking at older versions, that is exactly what this method used to do.

There doesn’t seem to be one specific part of this that is slowing things down. It looks like 6 queries are executed every time HibernatePatientDAO.getPatients(String query, boolean includeVoided, Integer start, Integer length) is executed, which is what gets called by EncounterServiceImpl.getEncountersByPatientIdentifier(). This method appears to be very fast until the database contains a fair amount of data. Here is what I’m using in our test environment:

60,000 patient records

60,000 person_name records

700,000 person_attribute records

160,000 patient_identifier records

I noticed that this issue is noticeable with as few as 20,000 patient records and 170,000 person_attribute records.

I’m noticed this same problem as well after upgrading to 2.1.x. The “getEncountersByIPatientIdentifier” now does more than searching by identifier. We should most likely deprecate this method if we aren’t planning on providing fast identifier searching going forward.

I’m figuring the idea was that with the switch to Lucene, the search speed should be improved so that the you don’t need to have a special “fast” identifier search… however, I thought that Lucene was not included until 2.1? Do I have that right, @raff?

(This actually affects the Core Apps patient search widget, because it is configured to search first by identifier and then by full name (for performance reasons) and now it basically does the same search twice (I have this ticketed, but don’t have the ticket number handy).)

Thanks and take care, Mark

IIRC Lucene is included in core from 2.0.x, but it’s only used for Concept searching there. Starting in 2.1.x it’s used for patient searching as well.

If we have lost the ability to search only by identifier we should add this back in. (I would consider it a bugfix, so suitable to backport to 2.0.x.)

I do think this is the case @darius… so @david5780 feel free to ticket this as a bug.

Take care, Mark

Thank you for looking into this. Ticket is https://issues.openmrs.org/browse/TRUNK-5362

Hallo I have worked on this ticket and best available solution was to put back the method in HibernatePatientsDAO.java that queried patients according to patient Identifier.

Here is the PR: TRUNK-5362:Issue with method in EncounterService causing extreme slow… by suubi-joshua · Pull Request #4303 · openmrs/openmrs-core · GitHub @david5780 @darius @mogoodrich @dkayiwa