Skip to content
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

[BUG] Calling getMillis() in Painless script is slow #3156

Closed
mbaranczak opened this issue May 3, 2022 · 10 comments · Fixed by #3346
Closed

[BUG] Calling getMillis() in Painless script is slow #3156

mbaranczak opened this issue May 3, 2022 · 10 comments · Fixed by #3346
Labels
benchmarking Issues related to benchmarking or performance. bug Something isn't working Indexing & Search

Comments

@mbaranczak
Copy link

Describe the bug

We had a sorting script that called getMillis() on a date field. We noticed that the script was unusually slow for queries that matched a large number of results, and determined that getMillis() was the bottleneck. Removing that call resulted in a 10-fold speed-up.

I found this bug report for ElasticSearch 6.5.0, which looks very similar to what I ran into. It says that the bug was fixed; maybe the fix never made it into OpenSearch, maybe the bug came back. elastic/elasticsearch#35754

I had good results with the work-around suggested in that report (replacing getMillis() with toInstant().toEpochMilli()).

To Reproduce

On an index with a datetime field called originalDate, and a large number of documents (a million or more), run this search:

{
  "_source": ["id","originalDate"],
  "sort": {
    "_script": {
      "type": "number",
      "order": "asc",
      "script": {
        "source": "return doc[\"originalDate\"].value.getMillis();"
	  }
	}
  }
}

Host/Environment:

Amazon OpenSearch service v1.0

@mbaranczak mbaranczak added bug Something isn't working untriaged labels May 3, 2022
@dblock
Copy link
Member

dblock commented May 3, 2022

Would love a PR, @mbaranczak, thank you!

@mbaranczak mbaranczak changed the title Calling getMillis() in Painless script is slow [BUG] Calling getMillis() in Painless script is slow May 3, 2022
@andrross andrross added Indexing & Search benchmarking Issues related to benchmarking or performance. and removed untriaged labels May 4, 2022
@reta
Copy link
Collaborator

reta commented May 11, 2022

@mbaranczak interesting, here is the getMillis() implementation, I believe this slowness comes from the logDeprecatedMethod calls?

    @Deprecated
    public long getMillis() {
        logDeprecatedMethod("getMillis()", "toInstant().toEpochMilli()");
        return dt.toInstant().toEpochMilli();
    }

@dblock this method is deprecated and should not be used in general, should such deprecated methods in 2.0?

@mbaranczak
Copy link
Author

Is it really necessary to deprecate/remove this method? If getMillis() is just an alias for toInstanct().toEpochMilli(), what's the harm in keeping it?

And here's another thing: since I'm using OpenSearch in a managed environment, I don't have access to the server log (or wherever this deprecation warning gets written to). So I don't even see the warning. In my use case, logDeprecatedMethod does nothing useful, and just wastes CPU time. Would it make sense to add a field to the response for deprecation warnings (and possibly other warnings)?

@reta
Copy link
Collaborator

reta commented May 11, 2022

Is it really necessary to deprecate/remove this method? If getMillis() is just an alias for toInstanct().toEpochMilli(), what's the harm in keeping it?

@mbaranczak the deprecation story goes back to Elasticsearch, this is what Opensearch inherited.

Would it make sense to add a field to the response for deprecation warnings (and possibly other warnings)?

I believe you should get them inside Warning response header: https://github.com/elastic/elasticsearch/pull/55941/files

@mbaranczak
Copy link
Author

@reta I'm not seeing any warnings in the headers, either. Are the warning headers always on, or is there some switch to turn them on and off?

@reta
Copy link
Collaborator

reta commented May 12, 2022

@mbaranczak sorry, my bad, it is OFF by default but could be configured by adding

appender.header_warning.type = HeaderWarningAppender
appender.header_warning.name = header_warning                                                

to config/log4j2.properties. Is it something you could pull off? Here is the example of the Warning header returned:

Warning: 299 OpenSearch-3.0.0-SNAPSHOT-10bff0c9f5b9ca78b3dc50f5c704dabf41b9d535 "Use of the joda time method [getMillis()] is deprecated. Use [toInstant().toEpochMilli()] instead."

@dblock
Copy link
Member

dblock commented May 16, 2022

Is it really necessary to deprecate/remove this method? If getMillis() is just an alias for toInstanct().toEpochMilli(), what's the harm in keeping it?

I don't know why it was deprecated in Elasticsearch. I suppose nobody wants to keep methods that don't actually do anything other than call other methods that do the same thing around. Major versions have other breaking changes, and I think the right thing to do here would be to remove the deprecated method from 3.0 (main). This way it will break hard in a major upgrade instead of causing a silent performance regression. Want to PR it if you agree?

@reta
Copy link
Collaborator

reta commented May 16, 2022

@dblock 👍 to that, will create an issue + change

@mbaranczak
Copy link
Author

@reta I'm not running my own server, I'm using the Amazon OpenSearch Service. No, I don't see any way to change the log4j properties.

@reta
Copy link
Collaborator

reta commented May 16, 2022

Amazon OpenSearch Service

Got it, I am not sure there are any other way to get these deprecation warning without accessing logs or changing configuration. You could probably open a case with AWS regarding that, those are vendor-specific constraints apparently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
benchmarking Issues related to benchmarking or performance. bug Something isn't working Indexing & Search
Projects
None yet
4 participants