GROUP BY on two large joined tables
Sorry, but you have designed yourself into a corner.

Strike 1:  EAV (key-value) schema sucks when the tables get large.  Further discussion and possible workarounds:  http://mysql.rjweb.org/doc.php/eav

Strike 2:  GUIDs (and UUIDs, MD5s, etc) suck as KEYs because they are so random.  Further discussion and a possible (but unlikely) workaround:  http://mysql.rjweb.org/doc.php/uuid

Your best choice may be to keep buying RAM so that everything can be cached.  And/or switch from spinning drives to SSDs.  Of course, neither hardware solution scales well.

Software solution involves a major rework of the schema and application code.  That is beyond the scope of this forum, other than to point you at those two blogs.

As for your specific questions:


  On the explain I always get a “Using where; Using index; Using temporary; Using filesort” on the Person table.  Why does MySql need to sort the Person table before joining to PersonData?


What you are seeing is bogus.  EXPLAIN likes to put those flags on the first line, even though they might apply to some other line.  If you have a new enough version of MySQL, do EXPLAIN FORMAT=JSON SELECT ...; it should spell out things correctly.


  Why does MySql generally decline to use the PersonID/FieldID/Value index? Is there a better index I could use? I assumed I needed the PersonID in the index to help with the join.


I need to see SHOW CREATE TABLE.  But here is a guess...  If the WHERE clause matches more than ~20%, it will choose to do a table scan because it is likely to be faster.  Another guess:  You have PRIMARY KEY(person, field) and INDEX(person, field, value)??  And you are using InnoDB??  The PK includes all columns and is sorted by (person, field).  That's identical to the secondary key!  So, the optimizer may as well flip a coin to decide between them.

Anyway, it says "Using index"; that about as efficient as it gets.