The code segment below has been extracted from a larger project. In short, I have an MXD which I want to generate multiple PDFs based on different criteria. The code below works. It loops through each of the layers within the MXD and updates the definitionQuery and the results are fine. On my desktop, the part of the code that sets the definitionQuery takes about 2 seconds, but the published code on the server takes over 40 seconds. Since that bit of code is called for each item in layer_parameter_list, the time of the report jumps from about a minute to multiple minutes.

When I update the defintionQuery, does the MXD get written to the drive? Does it re-filter the data then? On the server, the scratch is on a shared drive which could explain why it is slower. What can I do to improve performance? Can I tell the MXD not to be written? If the re-filtering is occurring, can I disable that until all definitionQuerys have been updated for all layers?

def function_that_iterates_over_data_and_generates_pdf_pages_from_mxd(mxd, extent):
    layer_parameter_list = [
        # field 1,    field 2,  field 3
        ['Company1', 'Value X',    'Value 1'],
        ['Company1', 'Value Y',    'Value 2'],

        ['Company2', 'Value X',    'Value 1'],
        ['Company2', 'Value Y',    'Value 2'],

    layer_queries = [
        ['layer_1', """"FIELD_1"='{0}' and "FIELD_2"='{1}'""",
                    """"FIELD_1"='{0}'' and "FIELD_2"='{1}'"""],
        ['layer_2', """"FIELD_2"='{1}' and "FIELD_3"='{2}'""",
                    """"FIELD_2"='{1}'' and "FIELD_3"='{2}'"""],
        ['layer_3', """"FIELD_1"='{0}' and "FIELD_3"='{2}'""",
                    """"FIELD_1"='{0}'' and "FIELD_3"='{2}'"""],

    dfs = arcpy.mapping.ListDataFrames(mxd)

    lyr_dict = {}
    for df in dfs:
        # Take opportunity to zoom each Dataframe as we build our
        # dictionary
        df.extent = extent
        for lyr in arcpy.mapping.ListLayers(mxd, '', df):
            if lyr.isFeatureLayer or lyr.isServiceLayer:
                lyr_dict[lyr.name, df.name] = lyr

    for (page_number, query_parameters) in enumerate(layer_parameter_list):
        # this block takes ~2 seconds on my desktop, but 40+ seconds on the server
        for (dfi, df) in enumerate(dfs):
            for layer_query in layer_queries:
                criteria = layer_query[dfi + 1].format(*query_parameters)
                arcpy.AddMessage("Criteria: " + criteria)#this was the problem line
                lyr = lyr_dict[layer_query[0], df.name]
                lyr.definitionQuery = criteria

        file_name = 'Page_{0}'.format('%02s' % page_number)
        arcpy.mapping.ExportToPDF(mxd, file_name)

EDIT: added back in the AddMessage line which was the cause of the slow down.


1 Answer 1


It turns out the problem was not related to the definitionQuery at all. It was the logging that was killing my performance. For my example code, I had stripped out the logging for the sake of space. Apparently INFO level logging is very slow.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.